// Protocol Buffers for Objective C
//
// Copyright 2010 Booyah Inc.
// Copyright 2008 Cyrus Najmabadi
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#import "CodedOutputStream.h"
#import "RingBuffer.h"
#import "Message.h"
#import "Utilities.h"
#import "WireFormat.h"
#import "UnknownFieldSetBuilder.h"
#import "UnknownFieldSet.h"


@implementation PBCodedOutputStream

const SInt32 DEFAULT_BUFFER_SIZE = 4 * 1024;


- (id)initWithOutputStream:(NSOutputStream*)_output data:(NSMutableData*)data {
	if ( (self = [super init]) ) {
		output = _output;
		buffer = [[RingBuffer alloc] initWithData:data];
	}
	return self;
}

+ (PBCodedOutputStream*)streamWithOutputStream:(NSOutputStream*)output bufferSize:(SInt32)bufferSize {
	NSMutableData *data = [NSMutableData dataWithLength:bufferSize];
	return [[PBCodedOutputStream alloc] initWithOutputStream:output data:data];
}


+ (PBCodedOutputStream*)streamWithOutputStream:(NSOutputStream*)output {
	return [PBCodedOutputStream streamWithOutputStream:output bufferSize:DEFAULT_BUFFER_SIZE];
}


+ (PBCodedOutputStream*)streamWithData:(NSMutableData*)data {
	return [[PBCodedOutputStream alloc] initWithOutputStream:nil data:data];
}


- (void)flush {
	if (output == nil) {
		// We're writing to a single buffer.
		@throw [NSException exceptionWithName:@"OutOfSpace" reason:@"" userInfo:nil];
	}
	
	[buffer flushToOutputStream:output];
}


- (void)writeRawByte:(uint8_t)value {
	while (![buffer appendByte:value]) {
        [self flush];
	}
}


- (void)writeRawData:(const NSData*)data {
	[self writeRawData:data offset:0 length:(SInt32)data.length];
}


- (void)writeRawData:(const NSData*)value offset:(SInt32)offset length:(SInt32)length {
	while (length > 0) {
		SInt32 written = [buffer appendData:value offset:offset length:length];
		offset += written;
		length -= written;
		if (!written || length > 0) {
            [self flush];
		}
	}
}


- (void)writeDoubleNoTag:(Float64)value {
	[self writeRawLittleEndian64:convertFloat64ToInt64(value)];
}


/** Write a {@code double} field, including tag, to the stream. */
- (void)writeDouble:(SInt32)fieldNumber value:(Float64)value {
	[self writeTag:fieldNumber format:PBWireFormatFixed64];
	[self writeDoubleNoTag:value];
}


- (void)writeFloatNoTag:(Float32)value {
	[self writeRawLittleEndian32:convertFloat32ToInt32(value)];
}


/** Write a {@code float} field, including tag, to the stream. */
- (void)writeFloat:(SInt32)fieldNumber value:(Float32)value {
	[self writeTag:fieldNumber format:PBWireFormatFixed32];
	[self writeFloatNoTag:value];
}


- (void)writeUInt64NoTag:(SInt64)value {
	[self writeRawVarint64:value];
}


/** Write a {@code uint64} field, including tag, to the stream. */
- (void)writeUInt64:(SInt32)fieldNumber value:(SInt64)value {
	[self writeTag:fieldNumber format:PBWireFormatVarint];
	[self writeUInt64NoTag:value];
}


- (void)writeInt64NoTag:(SInt64)value {
	[self writeRawVarint64:value];
}


/** Write an {@code int64} field, including tag, to the stream. */
- (void)writeInt64:(SInt32)fieldNumber value:(SInt64)value {
	[self writeTag:fieldNumber format:PBWireFormatVarint];
	[self writeInt64NoTag:value];
}


- (void)writeInt32NoTag:(SInt32)value {
	if (value >= 0) {
		[self writeRawVarint32:value];
	} else {
		// Must sign-extend
		[self writeRawVarint64:value];
	}
}


/** Write an {@code int32} field, including tag, to the stream. */
- (void)writeInt32:(SInt32)fieldNumber value:(SInt32)value {
	[self writeTag:fieldNumber format:PBWireFormatVarint];
	[self writeInt32NoTag:value];
}


- (void)writeFixed64NoTag:(SInt64)value {
	[self writeRawLittleEndian64:value];
}


/** Write a {@code fixed64} field, including tag, to the stream. */
- (void)writeFixed64:(SInt32)fieldNumber value:(SInt64)value {
	[self writeTag:fieldNumber format:PBWireFormatFixed64];
	[self writeFixed64NoTag:value];
}


- (void)writeFixed32NoTag:(SInt32)value {
	[self writeRawLittleEndian32:value];
}


/** Write a {@code fixed32} field, including tag, to the stream. */
- (void)writeFixed32:(SInt32)fieldNumber value:(SInt32)value {
	[self writeTag:fieldNumber format:PBWireFormatFixed32];
	[self writeFixed32NoTag:value];
}


- (void)writeBoolNoTag:(BOOL)value {
	[self writeRawByte:(value ? 1 : 0)];
}


/** Write a {@code bool} field, including tag, to the stream. */
- (void)writeBool:(SInt32)fieldNumber value:(BOOL)value {
	[self writeTag:fieldNumber format:PBWireFormatVarint];
	[self writeBoolNoTag:value];
}


- (void)writeStringNoTag:(const NSString*)value {
	NSData* data = [value dataUsingEncoding:NSUTF8StringEncoding];
	[self writeRawVarint32:(SInt32)data.length];
	[self writeRawData:data];
}


/** Write a {@code string} field, including tag, to the stream. */
- (void)writeString:(SInt32)fieldNumber value:(const NSString*)value {
	[self writeTag:fieldNumber format:PBWireFormatLengthDelimited];
	[self writeStringNoTag:value];
}


- (void)writeGroupNoTag:(SInt32)fieldNumber value:(const id<PBMessage>)value {
	[value writeToCodedOutputStream:self];
	[self writeTag:fieldNumber format:PBWireFormatEndGroup];
}


/** Write a {@code group} field, including tag, to the stream. */
- (void)writeGroup:(SInt32)fieldNumber value:(const id<PBMessage>)value {
	[self writeTag:fieldNumber format:PBWireFormatStartGroup];
	[self writeGroupNoTag:fieldNumber value:value];
}


- (void)writeUnknownGroupNoTag:(SInt32)fieldNumber value:(const PBUnknownFieldSet*)value {
	[value writeToCodedOutputStream:self];
	[self writeTag:fieldNumber format:PBWireFormatEndGroup];
}


/** Write a group represented by an {@link PBUnknownFieldSet}. */
- (void)writeUnknownGroup:(SInt32)fieldNumber value:(const PBUnknownFieldSet*)value {
	[self writeTag:fieldNumber format:PBWireFormatStartGroup];
	[self writeUnknownGroupNoTag:fieldNumber value:value];
}


- (void)writeMessageNoTag:(const id<PBMessage>)value {
	[self writeRawVarint32:[value serializedSize]];
	[value writeToCodedOutputStream:self];
}


/** Write an embedded message field, including tag, to the stream. */
- (void)writeMessage:(SInt32)fieldNumber value:(const id<PBMessage>)value {
	[self writeTag:fieldNumber format:PBWireFormatLengthDelimited];
	[self writeMessageNoTag:value];
}


- (void)writeDataNoTag:(const NSData*)value {
	[self writeRawVarint32:(SInt32)value.length];
	[self writeRawData:value];
}


/** Write a {@code bytes} field, including tag, to the stream. */
- (void)writeData:(SInt32)fieldNumber value:(const NSData*)value {
	[self writeTag:fieldNumber format:PBWireFormatLengthDelimited];
	[self writeDataNoTag:value];
}


- (void)writeUInt32NoTag:(SInt32)value {
	[self writeRawVarint32:value];
}


/** Write a {@code uint32} field, including tag, to the stream. */
- (void)writeUInt32:(SInt32)fieldNumber value:(SInt32)value {
	[self writeTag:fieldNumber format:PBWireFormatVarint];
	[self writeUInt32NoTag:value];
}


- (void)writeEnumNoTag:(SInt32)value {
	[self writeRawVarint32:value];
}


- (void)writeEnum:(SInt32)fieldNumber value:(SInt32)value {
	[self writeTag:fieldNumber format:PBWireFormatVarint];
	[self writeEnumNoTag:value];
}


- (void)writeSFixed32NoTag:(SInt32)value {
	[self writeRawLittleEndian32:value];
}


/** Write an {@code sfixed32} field, including tag, to the stream. */
- (void)writeSFixed32:(SInt32)fieldNumber value:(SInt32)value {
	[self writeTag:fieldNumber format:PBWireFormatFixed32];
	[self writeSFixed32NoTag:value];
}


- (void)writeSFixed64NoTag:(SInt64)value {
	[self writeRawLittleEndian64:value];
}


/** Write an {@code sfixed64} field, including tag, to the stream. */
- (void)writeSFixed64:(SInt32)fieldNumber value:(SInt64)value {
	[self writeTag:fieldNumber format:PBWireFormatFixed64];
	[self writeSFixed64NoTag:value];
}


- (void)writeSInt32NoTag:(SInt32)value {
	[self writeRawVarint32:encodeZigZag32(value)];
}


/** Write an {@code sint32} field, including tag, to the stream. */
- (void)writeSInt32:(SInt32)fieldNumber value:(SInt32)value {
	[self writeTag:fieldNumber format:PBWireFormatVarint];
	[self writeSInt32NoTag:value];
}


- (void)writeSInt64NoTag:(SInt64)value {
	[self writeRawVarint64:encodeZigZag64(value)];
}


/** Write an {@code sint64} field, including tag, to the stream. */
- (void)writeSInt64:(SInt32)fieldNumber value:(SInt64)value {
	[self writeTag:fieldNumber format:PBWireFormatVarint];
	[self writeSInt64NoTag:value];
}


/**
 * Write a MessageSet extension field to the stream.  For historical reasons,
 * the wire format differs from normal fields.
 */
- (void)writeMessageSetExtension:(SInt32)fieldNumber value:(const id<PBMessage>)value {
	[self writeTag:PBWireFormatMessageSetItem format:PBWireFormatStartGroup];
	[self writeUInt32:PBWireFormatMessageSetTypeId value:fieldNumber];
	[self writeMessage:PBWireFormatMessageSetMessage value:value];
	[self writeTag:PBWireFormatMessageSetItem format:PBWireFormatEndGroup];
}


/**
 * Write an unparsed MessageSet extension field to the stream.  For
 * historical reasons, the wire format differs from normal fields.
 */
- (void)writeRawMessageSetExtension:(SInt32)fieldNumber value:(const NSData*)value {
	[self writeTag:PBWireFormatMessageSetItem format:PBWireFormatStartGroup];
	[self writeUInt32:PBWireFormatMessageSetTypeId value:fieldNumber];
	[self writeData:PBWireFormatMessageSetMessage value:value];
	[self writeTag:PBWireFormatMessageSetItem format:PBWireFormatEndGroup];
}


- (void)writeTag:(SInt32)fieldNumber format:(SInt32)format {
	[self writeRawVarint32:PBWireFormatMakeTag(fieldNumber, format)];
}


- (void)writeRawVarint32:(SInt32)value {
	while (YES) {
		if ((value & ~0x7F) == 0) {
			[self writeRawByte:value];
			return;
		} else {
			[self writeRawByte:((value & 0x7F) | 0x80)];
			value = logicalRightShift32(value, 7);
		}
	}
}


- (void)writeRawVarint64:(SInt64)value {
	while (YES) {
		if ((value & ~0x7FL) == 0) {
			[self writeRawByte:((SInt32)value)];
			return;
		} else {
			[self writeRawByte:(((SInt32)value & 0x7F) | 0x80)];
			value = logicalRightShift64(value, 7);
		}
	}
}


- (void)writeRawLittleEndian32:(SInt32)value {
	[self writeRawByte:((value      ) & 0xFF)];
	[self writeRawByte:((value >>  8) & 0xFF)];
	[self writeRawByte:((value >> 16) & 0xFF)];
	[self writeRawByte:((value >> 24) & 0xFF)];
}


- (void)writeRawLittleEndian64:(SInt64)value {
	[self writeRawByte:((SInt32)(value      ) & 0xFF)];
	[self writeRawByte:((SInt32)(value >>  8) & 0xFF)];
	[self writeRawByte:((SInt32)(value >> 16) & 0xFF)];
	[self writeRawByte:((SInt32)(value >> 24) & 0xFF)];
	[self writeRawByte:((SInt32)(value >> 32) & 0xFF)];
	[self writeRawByte:((SInt32)(value >> 40) & 0xFF)];
	[self writeRawByte:((SInt32)(value >> 48) & 0xFF)];
	[self writeRawByte:((SInt32)(value >> 56) & 0xFF)];
}

@end
