/* Test/example program for the base library

   Copyright (C) 2005 Free Software Foundation, Inc.
   
  Copying and distribution of this file, with or without modification,
  are permitted in any medium without royalty provided the copyright
  notice and this notice are preserved.

   This file is part of the GNUstep Base Library.
*/
/******************************************************************************
* Module    :   NSMutableData(NSData) --- Black Box test module for the
*               *Data classes to make sure that methods that raise exceptions
*               do so, and that the exceptions are raised properly.
*
* Author    :   John W. M. Stevens

...............................................................................
15 April 1997

******************************************************************************/

#include    <stdio.h>
#include    <Foundation/NSData.h>
#include    <Foundation/NSException.h>
#include    <Foundation/NSRange.h>
#include    <Foundation/NSSerialization.h>
#include    <Foundation/NSAutoreleasePool.h>

/*  Data for stuffing into *Data objects.  I like printable data, as it
*   gives a quick visual check mechanism, but it has the disadvantage
*   of not checking for 8 bit cleanliness.
*/
char    *testString = "Test string for mutable data and archiver classes.";
char    *subString  = "Sub String";

/*-----------------------------------------------------------------------------
| Routine   :   TestNSMutableData() --- Create an instance of an NSMutableData
|               class, initialize it with a C string (to have something
|               printable for tests) and invoke the two methods that
|               should raise NSRangeException exceptions using ranges that
|               cross both edges of the buffer boundary.
|
| Notes     :   Please see work logs for discussion.
-----------------------------------------------------------------------------*/

void
TestNSMutableData(void)
{
    auto    NSMutableData   *nsMutData;
    auto    char            *str;
    auto    NSRange         range;

    /*  Allocate and initialize an instance of an NSMutableData
    *   class.
    */
    nsMutData = [NSMutableData dataWithLength: strlen( testString ) + 1];
    str = (char *) [nsMutData mutableBytes];
    strcpy(str, testString);

    /*  Get contents, display.  */
    str = NULL;
    str = (char *) [nsMutData mutableBytes];
    printf("NSMutableData Test ---------------------------------------------"
           "---------------\n"
           "1) String: (%s)\n", str);

    /*  Attempt to force Range exception by having range start before
    *   zero.
    */
NS_DURING
    range = NSMakeRange(-2, strlen( subString ));
    [nsMutData replaceBytesInRange: range
               withBytes          : subString ];
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  Attempt to force another Range exception.   */
NS_DURING
    range = NSMakeRange(41, strlen( subString ));
    [nsMutData replaceBytesInRange: range
               withBytes          : subString ];
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  Attempt to force another Range exception.   */
NS_DURING
    range = NSMakeRange(42, strlen( subString ));
    [nsMutData replaceBytesInRange: range
               withBytes          : subString ];
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  How about a length that is less than zero?  */
NS_DURING
    range = NSMakeRange(6, -3.0);
    [nsMutData replaceBytesInRange: range
               withBytes          : subString ];
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  Attempt to force Range exception by having range start before
    *   zero.
    */
NS_DURING
    range = NSMakeRange(-2, strlen( subString ));
    [nsMutData resetBytesInRange: range];
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  Attempt to force another Range exception.   */
NS_DURING
    range = NSMakeRange(41, strlen( subString ));
    [nsMutData resetBytesInRange: range];
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  Attempt to force another Range exception.   */
NS_DURING
    range = NSMakeRange(42, strlen( subString ));
    [nsMutData resetBytesInRange: range];
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  How about a length less than zero?  */
NS_DURING
    range = NSMakeRange(6.0, -3.0);
    [nsMutData resetBytesInRange: range];
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  Get contents, display.  */
    str = NULL;
    str = (char *) [nsMutData mutableBytes];
    printf("2) String: (%s)\n", str);

    /*  Attempt to force an out of memory exception.    */
#if 0
    for ( ; ; )
    {
        /*  Append. */
        [nsMutData appendBytes: testString
                   length     : strlen( testString ) + 1];

        /*  Show current value. */
        printf("%9u\r", [nsMutData length]);
    }
#endif
}

/*-----------------------------------------------------------------------------
| Routine   :   TestNSData() --- Create an instance of an NSData
|               class, initialize it with a C string (to have something
|               printable for tests) and invoke the two methods that
|               should raise NSRangeException exceptions using ranges that
|               cross both edges of the buffer boundary.
|
| Notes     :   Please see work logs for discussion.
-----------------------------------------------------------------------------*/

void
TestNSData(void)
{
    auto    NSData          *nsData;
    auto    NSData          *newNsData;
    auto    char            *str;
    auto    char            bfr[128];
    auto    NSRange         range;

    /*  Allocate and initialize an instance of an NSData
    *   class.
    */
    nsData = [NSData dataWithBytes: testString
                     length       : (unsigned int) strlen( testString ) + 1];

    /*  Get contents, display.  */
    str = (char *) [nsData bytes];
    printf("NSData Test ----------------------------------------------------"
           "---------------\n"
           "1) String: (%s)\n", str);

    /*  Attempt to force Range exception by having range start before
    *   zero.
    */
NS_DURING
    /*  Get buffer piece.   */
    range = NSMakeRange(-2.0, 6.0);
    [nsData getBytes: bfr
            range   : range];

    /*  Print buffer piece. */
    bfr[6] = '\0';
    printf("    A) Buffer: (%s)\n", bfr);
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  Attempt to force another Range exception.   */
NS_DURING
    /*  Get piece.  */
    range = NSMakeRange(41, strlen( subString ));
    [nsData getBytes: bfr
            range   : range];

    /*  Print buffer piece. */
    bfr[strlen( subString )] = '\0';
    printf("    B) Buffer: (%s)\n", bfr);
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  Attempt to force another Range exception.   */
NS_DURING
    range = NSMakeRange(42, strlen( subString ));
    [nsData getBytes: bfr
            range   : range];

    /*  Print buffer piece. */
    bfr[strlen( subString )] = '\0';
    printf("    C) Buffer: (%s)\n", bfr);
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  How about less than zero length?    */
NS_DURING
    range = NSMakeRange(5.0, -4.0);
    [nsData getBytes: bfr
            range   : range];

    /*  Print buffer piece. */
    bfr[strlen( subString )] = '\0';
    printf("    C) Buffer: (%s)\n", bfr);
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

/*=================== subDataWithRange ======================================*/
    /*  Attempt to force Range exception by having range start before
    *   zero.
    */
NS_DURING
    /*  Get buffer piece.   */
    range = NSMakeRange(-2.0, 6.0);
    newNsData = [nsData subdataWithRange: range];

    /*  Print buffer piece. */
    [newNsData getBytes: bfr];
    bfr[6] = '\0';
    printf("    D) Buffer: (%s)\n", bfr);
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  Attempt to force another Range exception.   */
NS_DURING
    /*  Get buffer piece.   */
    range = NSMakeRange(41, strlen( subString ));
    newNsData = [nsData subdataWithRange: range];

    /*  Print buffer piece. */
    [newNsData getBytes: bfr];
    bfr[strlen( subString )] = '\0';
    printf("    E) Buffer: (%s)\n", bfr);
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  Attempt to force another Range exception.   */
NS_DURING
    /*  Get buffer piece.   */
    range = NSMakeRange(42, strlen( subString ));
    newNsData = [nsData subdataWithRange: range];

    /*  Print buffer piece. */
    [newNsData getBytes: bfr];
    bfr[strlen( subString )] = '\0';
    printf("    F) Buffer: (%s)\n", bfr);
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  How about a length less than zero?  */
NS_DURING
    /*  Get buffer piece.   */
    range = NSMakeRange(9.0, -6.0);
    newNsData = [nsData subdataWithRange: range];

    /*  Print buffer piece. */
    [newNsData getBytes: bfr];
    bfr[strlen( subString )] = '\0';
    printf("    F) Buffer: (%s)\n", bfr);
NS_HANDLER
    fprintf(stderr,
            "%s %d : Exception %s - %s\n",
            __FILE__,
            __LINE__,
            [[localException name]   cString],
            [[localException reason] cString]);
NS_ENDHANDLER

    /*  Get contents, display.  */
    str = NULL;
    str = (char *) [nsData bytes];
    printf("2) String: (%s)\n", str);
}

int
main(int    argc,
     char   **argv)
{
    NSAutoreleasePool	*arp = [NSAutoreleasePool new];

    /*  Test NSMutableData. */
    TestNSMutableData();

    /*  Test NSData.    */
    TestNSData();
    [arp release];
    return 0;
}
