# Code coverage report for lib/writable_streambuffer.js

## Statements: 96.77% (60 / 62) Branches: 90.63% (29 / 32) Functions: 100% (9 / 9) Lines: 98.25% (56 / 57) Ignored: none

All files » lib/ » writable_streambuffer.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    981

    1
    10

    10

    10
    10
    10

    10
    10

    10
    10

    10
    5

    10
    5

    10
    2

    1
    1

    1

    1

    1

    10
    8

    7
    7

    7
    1

    7
    7

    10
    10
    2

    2
    2
    2

    10
    11

    10
    2
    2
    2

    8
    8
    8
    8

    10

    10
    1
    1
    1
    1

    10
    4
    4

    1
     var util = require("util"),
    	stream = require("stream"),
    	constants = require("./constants");

    // TODO: clear up specs on returning false from a write and emitting a drain event.
    // Does this mean if I return false from a write, I should ignore any write requests between that false return and the drain event?
    var WritableStreamBuffer = module.exports = function(opts) {
    	var that = this;

    	stream.Stream.call(this);

    	opts = opts || {};
    	var initialSize = opts.initialSize || constants.DEFAULT_INITIAL_SIZE;
    	var incrementAmount = opts.incrementAmount || constants.DEFAULT_INCREMENT_AMOUNT;

    	var buffer = new Buffer(initialSize);
    	var size = 0;

    	this.writable = true;
    	this.readable = false;

    	this.size = function() {
    		return size;
    	};

    	this.maxSize = function() {
    		return buffer.length;
    	};

    	this.getContents = function(length) {
    		if(!size) return false;

    		var data = new Buffer(Math.min(length || size, size));
    		buffer.copy(data, 0, 0, data.length);

    		Iif(data.length < size)
    			buffer.copy(buffer, 0, data.length);

    		size -= data.length;

    		return data;
    	};

    	this.getContentsAsString = function(encoding, length) {
    		if(!size) return false;

    		var data = buffer.toString(encoding || "utf8", 0, Math.min(length || size, size));
    		var dataLength = Buffer.byteLength(data);

    		if(dataLength < size)
    			buffer.copy(buffer, 0, dataLength);

    		size -= dataLength;
    		return data;
    	};

    	var increaseBufferIfNecessary = function(incomingDataSize) {
    		if((buffer.length - size) < incomingDataSize) {
    			var factor = Math.ceil((incomingDataSize - (buffer.length - size)) / incrementAmount);

    			var newBuffer = new Buffer(buffer.length + (incrementAmount * factor));
    			buffer.copy(newBuffer, 0, 0, size);
    			buffer = newBuffer;
    		}
    	};

    	this.write = function(data, encoding, callback) {
    		if(!that.writable) return;

    		if(Buffer.isBuffer(data)) {
    			increaseBufferIfNecessary(data.length);
    			data.copy(buffer, size, 0);
    			size += data.length;
    		}
    		else {
    			data = data + "";
    			increaseBufferIfNecessary(Buffer.byteLength(data));
    			buffer.write(data, size, encoding || "utf8");
    			size += Buffer.byteLength(data);
    		}

    		Iif(typeof callback === "function") { callback() ;}
    	};

    	this.end = function() {
    		var args = Array.prototype.slice.apply(arguments);
    		Eif(args.length) that.write.apply(that, args);
    		that.emit('finish');
    		that.destroy();
    	};

    	this.destroySoon = this.destroy = function() {
    		that.writable = false;
    		that.emit("close");
    	};
    };
    util.inherits(WritableStreamBuffer, stream.Stream);