summaryrefslogblamecommitdiffstats
path: root/private/ntos/rtl/tprefix.c
blob: 27d7d69882cede41de3255e051ee829236fefc17 (plain) (tree)


















































































































































































































































































































































                                                                                                                                                               
/*++

Copyright (c) 1989  Microsoft Corporation

Module Name:

    tprefix.c

Abstract:

    Test program for the Prefix table package

Author:

    Gary Kimura     [GaryKi]    03-Aug-1989

Revision History:

--*/

#include <stdio.h>
#include <string.h>

#include "nt.h"
#include "ntrtl.h"

//
//  Routines and types for generating random prefixes
//

ULONG RtlRandom ( IN OUT PULONG Seed );
ULONG Seed;

PSZ AnotherPrefix(IN ULONG MaxNameLength);
ULONG AlphabetLength;

//PSZ Alphabet = "AlphaBravoCharlieDeltaEchoFoxtrotGolfHotelIndiaJuliettKiloLimaMikeNovemberOscarPapaQuebecRomeoSierraTangoUniformVictorWhiskeyXrayYankeeZulu";

PSZ Alphabet = "\
Aa\
BBbb\
CCCccc\
DDDDdddd\
EEEEEeeeee\
FFFFFFffffff\
GGGGGGGggggggg\
HHHHHHHHhhhhhhhh\
IIIIIIIIIiiiiiiiii\
JJJJJJJJJJjjjjjjjjjj\
KKKKKKKKKKKkkkkkkkkkkk\
LLLLLLLLLLLLllllllllllll\
MMMMMMMMMMMMMmmmmmmmmmmmmm\
NNNNNNNNNNNNNNnnnnnnnnnnnnnn\
OOOOOOOOOOOOOOOooooooooooooooo\
PPPPPPPPPPPPPPPPpppppppppppppppp\
QQQQQQQQQQQQQQQQQqqqqqqqqqqqqqqqqq\
RRRRRRRRRRRRRRRRRRrrrrrrrrrrrrrrrrrr\
SSSSSSSSSSSSSSSSSSSsssssssssssssssssss\
TTTTTTTTTTTTTTTTTTTTtttttttttttttttttttt\
UUUUUUUUUUUUUUUUUUUUUuuuuuuuuuuuuuuuuuuuuu\
VVVVVVVVVVVVVVVVVVVVVVvvvvvvvvvvvvvvvvvvvvvv\
WWWWWWWWWWWWWWWWWWWWWWWwwwwwwwwwwwwwwwwwwwwwww\
XXXXXXXXXXXXXXXXXXXXXXXXxxxxxxxxxxxxxxxxxxxxxxxx\
YYYYYYYYYYYYYYYYYYYYYYYYYyyyyyyyyyyyyyyyyyyyyyyyyy\
ZZZZZZZZZZZZZZZZZZZZZZZZZZzzzzzzzzzzzzzzzzzzzzzzzzzz";

#define BUFFER_LENGTH 8192

CHAR Buffer[BUFFER_LENGTH];
ULONG NextBufferChar = 0;

//
//  record structure and variables for the prefix table and it
//  elements
//

typedef struct _PREFIX_NODE {
    PREFIX_TABLE_ENTRY PfxEntry;
    STRING String;
} PREFIX_NODE;
typedef PREFIX_NODE *PPREFIX_NODE;

#define PREFIXES 512

PREFIX_NODE Prefixes[PREFIXES];

PREFIX_TABLE PrefixTable;

int
main(
    int argc,
    char *argv[]
    )
{
    ULONG i;
    PSZ Psz;

    PPREFIX_TABLE_ENTRY PfxEntry;
    PPREFIX_NODE PfxNode;

    STRING String;

    //
    //  We're starting the test
    //

    DbgPrint("Start Prefix Test\n");

    //
    //  Calculate the alphabet size for use by AnotherPrefix
    //

    AlphabetLength = strlen(Alphabet);

    //
    //  Initialize the prefix table
    //

    PfxInitialize(&PrefixTable);

    //
    //  Insert the root prefix
    //

    RtlInitString( &Prefixes[i].String, "\\" );
    if (PfxInsertPrefix( &PrefixTable,
                         &Prefixes[0].String,
                         &Prefixes[0].PfxEntry )) {
        DbgPrint("Insert root prefix\n");
    } else {
        DbgPrint("error inserting root prefix\n");
    }

    //
    //  Insert prefixes
    //

    Seed = 0;

    for (i = 1, Psz = AnotherPrefix(3);
         (i < PREFIXES) && (Psz != NULL);
         i += 1, Psz = AnotherPrefix(3)) {

        DbgPrint("[0x%x] = ", i);
        DbgPrint("\"%s\"", Psz);

        RtlInitString(&Prefixes[i].String, Psz);

        if (PfxInsertPrefix( &PrefixTable,
                             &Prefixes[i].String,
                             &Prefixes[i].PfxEntry )) {

            DbgPrint(" inserted in table\n");

        } else {

            DbgPrint(" already in table\n");

        }

    }

    //
    //  Enumerate the prefix table
    //

    DbgPrint("Enumerate Prefix Table the first time\n");

    for (PfxEntry = PfxNextPrefix(&PrefixTable, TRUE);
         PfxEntry != NULL;
         PfxEntry = PfxNextPrefix(&PrefixTable, FALSE)) {

        PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry);

        DbgPrint("%s\n", PfxNode->String.Buffer);

    }

    DbgPrint("Start Prefix search 0x%x\n", NextBufferChar);

    //
    //  Search for prefixes
    //

    for (Psz = AnotherPrefix(4); Psz != NULL; Psz = AnotherPrefix(4)) {

        DbgPrint("0x%x ", NextBufferChar);

        RtlInitString(&String, Psz);

        PfxEntry = PfxFindPrefix( &PrefixTable, &String, FALSE );

        if (PfxEntry == NULL) {

            PfxEntry = PfxFindPrefix( &PrefixTable, &String, TRUE );

            if (PfxEntry == NULL) {

                DbgPrint("Not found      \"%s\"\n", Psz);

                NOTHING;

            } else {

                PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry);

                DbgPrint("Case blind     \"%s\" is \"%s\"\n", Psz, PfxNode->String.Buffer);

                PfxRemovePrefix( &PrefixTable, PfxEntry );

            }

        } else {

            PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry);

            DbgPrint(    "Case sensitive \"%s\" is \"%s\"\n", Psz, PfxNode->String.Buffer);

            if (PfxNode != &Prefixes[0]) {

                PfxRemovePrefix( &PrefixTable, PfxEntry );

            }

        }

    }

    //
    //  Enumerate the prefix table
    //

    DbgPrint("Enumerate Prefix Table a second time\n");

    for (PfxEntry = PfxNextPrefix(&PrefixTable, TRUE);
         PfxEntry != NULL;
         PfxEntry = PfxNextPrefix(&PrefixTable, FALSE)) {

        PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry);

        DbgPrint("%s\n", PfxNode->String.Buffer);

    }

    //
    //  Now enumerate and zero out the table
    //

    for (PfxEntry = PfxNextPrefix(&PrefixTable, TRUE);
         PfxEntry != NULL;
         PfxEntry = PfxNextPrefix(&PrefixTable, FALSE)) {

        PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry);

        DbgPrint("Delete %s\n", PfxNode->String.Buffer);

        PfxRemovePrefix( &PrefixTable, PfxEntry );

    }

    //
    //  Enumerate again but this time the table should be empty
    //

    for (PfxEntry = PfxNextPrefix(&PrefixTable, TRUE);
         PfxEntry != NULL;
         PfxEntry = PfxNextPrefix(&PrefixTable, FALSE)) {

        PfxNode = CONTAINING_RECORD(PfxEntry, PREFIX_NODE, PfxEntry);

        DbgPrint("This Node should be gone \"%s\"\n", PfxNode->String.Buffer);

    }

    DbgPrint("End PrefixTest()\n");

    return TRUE;
}


PSZ
AnotherPrefix(IN ULONG MaxNameLength)
{
    ULONG AlphabetPosition;

    ULONG NameLength;
    ULONG IndividualNameLength;

    ULONG StartBufferPosition;
    ULONG i;
    ULONG j;

    //
    //  Check if there is enough room for another name
    //

    if (NextBufferChar > (BUFFER_LENGTH - (MaxNameLength * 4))) {
        return NULL;
    }

    //
    //  Where in the alphabet soup we start
    //

    AlphabetPosition = RtlRandom(&Seed) % AlphabetLength;

    //
    //  How many names we want in our prefix
    //

    NameLength = (RtlRandom(&Seed) % MaxNameLength) + 1;

    //
    //  Compute each name
    //

    StartBufferPosition = NextBufferChar;

    for (i = 0; i < NameLength; i += 1) {

        Buffer[NextBufferChar++] = '\\';

        IndividualNameLength = (RtlRandom(&Seed) % 3) + 1;

        for (j = 0; j < IndividualNameLength; j += 1) {

            Buffer[NextBufferChar++] = Alphabet[AlphabetPosition];
            AlphabetPosition = (AlphabetPosition + 1) % AlphabetLength;

        }

    }

    Buffer[NextBufferChar++] = '\0';

    return &Buffer[StartBufferPosition];

}