/*
* Copyright (c) 2008-2024 Jonathan Schleifer <js@nil.im>
*
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version 3.0 only,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* version 3.0 for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* version 3.0 along with this program. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#import "ObjFW.h"
#import "ObjFWTest.h"
@interface OFMemoryStreamTests: OTTestCase
@end
static const char string[] = "abcdefghijkl";
@implementation OFMemoryStreamTests
- (void)testReadOnlyMemoryStream
{
OFMemoryStream *stream = [OFMemoryStream
streamWithMemoryAddress: (char *)string
size: sizeof(string)
writable: false];
char buffer[10];
/*
* Test the lowlevel methods, as otherwise OFStream will do one big
* read and we will not test OFMemoryStream.
*/
OTAssertEqual([stream lowlevelReadIntoBuffer: buffer length: 5], 5);
OTAssertEqual(memcmp(buffer, "abcde", 5), 0);
OTAssertEqual([stream lowlevelReadIntoBuffer: buffer length: 3], 3);
OTAssertEqual(memcmp(buffer, "fgh", 3), 0);
OTAssertEqual([stream lowlevelReadIntoBuffer: buffer length: 10], 5);
OTAssertEqual(memcmp(buffer, "ijkl", 5), 0);
OTAssertTrue([stream lowlevelIsAtEndOfStream]);
OTAssertEqual([stream lowlevelSeekToOffset: 0 whence: OFSeekCurrent],
sizeof(string));
OTAssertTrue([stream lowlevelIsAtEndOfStream]);
OTAssertEqual([stream lowlevelSeekToOffset: 4 whence: OFSeekSet], 4);
OTAssertFalse([stream lowlevelIsAtEndOfStream]);
OTAssertEqual([stream lowlevelReadIntoBuffer: buffer length: 10], 9);
OTAssertEqual(memcmp(buffer, "efghijkl", 9), 0);
OTAssertEqual([stream lowlevelSeekToOffset: -2 whence: OFSeekEnd], 11);
OTAssertEqual([stream lowlevelReadIntoBuffer: buffer length: 10], 2);
OTAssertEqual(memcmp(buffer, "l", 2), 0);
OTAssertEqual([stream lowlevelReadIntoBuffer: buffer length: 10], 0);
OTAssertThrowsSpecific([stream lowlevelWriteBuffer: "" length: 1],
OFWriteFailedException);
}
- (void)testReadWriteMemoryStream
{
OFMutableData *data = [OFMutableData dataWithCapacity: 13];
OFMemoryStream *stream;
[data increaseCountBy: 13];
stream = [OFMemoryStream streamWithMemoryAddress: data.mutableItems
size: data.count
writable: true];
OTAssertEqual([stream lowlevelWriteBuffer: "abcde" length: 5], 5);
OTAssertEqual([stream lowlevelWriteBuffer: "fgh" length: 3], 3);
OTAssertEqual([stream lowlevelWriteBuffer: "ijkl" length: 5], 5);
OTAssertEqual(memcmp(data.items, string, data.count), 0);
OTAssertEqual([stream lowlevelSeekToOffset: -3 whence: OFSeekEnd], 10);
OTAssertThrowsSpecific([stream lowlevelWriteBuffer: "xyz" length: 4],
OFWriteFailedException);
}
- (void)testWritingTooMuchThrows
{
char buffer;
OFMemoryStream *stream = [OFMemoryStream
streamWithMemoryAddress: &buffer
size: 1
writable: true];
OTAssertThrowsSpecific([stream writeBuffer: "ab" length: 2],
OFWriteFailedException);
}
@end