gusucode.com > vnt工具箱matlab源码程序 > vnt/vnt/+vnt/+internal/DataBuffer.m

    classdef DataBuffer < handle
% DataBuffer Implements a FIFO data buffer.
%
%   This class is used internally to implement a data buffer. Creating the
%   buffer takes two input items:
%
%       1. The size of the buffer.
%       2. A single data item used to initialize the memory for buffer.
%          This data item is replicated to create the initial storage.
%
%   The class provides methods to push/pop data to/from the buffer. Items
%   can be pushed/popped singularly or as arrays. The buffer operation
%   itself works as follows:
%
%       1. The buffer is a FIFO. Oldest data pushed is the first data
%          popped from the buffer.
%       2. The first index is always the oldest and first read data. 
%       3. If the buffer is overrun, oldest data is discarded to make room
%          for new data.
%
%   See also VNT.

% Authors: Jaremy Pyle
% Copyright 2015 The MathWorks, Inc.

properties (SetAccess = 'private')
    % Size - The size of the data buffer.
    Size
    % Data - The actual data storage for the buffer.
    Data
    % Count - The number of real data items currently in the buffer.
    Count
end


methods
    
    function obj = DataBuffer(size, dataElement)
    % DataBuffer Construct a data buffer object.

        % Set the size of the buffer.
        obj.Size = size;
        % Set the starting count as zero.
        obj.Count = 0;
        % Initialize all of the data elements of the buffer. This is done
        % to hold memory for the buffer storage.
        obj.Data = repmat(dataElement, [1, obj.Size]);
    end
    
    function push(obj, newData)
    % push Put new data into the data buffer.
    %
    %   This method take the provided data item(s) and adds them to the
    %   appropriate location in the data buffer, while performing
    %   any required buffer management.
        
        % Determine how many new items there are.
        newCount = numel(newData);
        % Determine how many total data items we will have all together.
        totalCount = obj.Count + newCount;
        
        % Check if the the new items will completely fill the buffer.
        if newCount >= obj.Size
            % Overwrite the entire buffer with the the last new items in
            % enough quantity to fill the entire buffer.
            obj.Data(1:end) = newData(newCount-obj.Size+1:end);
            % Set the buffer size as maximum since it is full.
            obj.Count = obj.Size;
            return;
        end
        
        % Check if the the new items will fit within the buffer without overrun.
        if totalCount <= obj.Size
            % Set the new items in the buffer directly after the last known
            % entry that is already in the buffer.
            obj.Data(obj.Count+1:obj.Count+newCount) = newData;
            % Add the new item count to the existing item count.
            obj.Count = obj.Count + newCount;
            return;
        end
        
        % Determine by how many the new entries will overrun the buffer.
        overrunCount = totalCount - obj.Size;
        % Shift the existing buffer items down to make room for the new
        % items that would overrun the buffer.
        obj.Data = circshift(obj.Data, overrunCount*-1, 2);
        % Set the new items at the back end of the buffer.
        obj.Data(obj.Count-overrunCount+1:end) = newData;        
        % Set the buffer size as maximum since it is full.
        obj.Count = obj.Size;  
        % Send a warning about the overrun.
        warning(message('vnt:DataBuffer:Overrun', overrunCount));
    end
    
    function data = pop(obj, requestedCount)
    % pop Take existing data from the data buffer.
    %
    %   This method returns items from the data buffer. It returns the 
    %   count requested or whatever is available if less data is present 
    %   than requested.
        
        % Check if the requested item count is larger than the quantity of
        % items available in the buffer.
        if requestedCount >= obj.Count
            % Return the entire buffer.
            data = obj.Data(1:obj.Count);
            % Set the buffer count to zero.
            obj.Count = 0;
            return;
        end
        
        % Return from the beginning of the buffer up to the quantity of
        % items requested.
        data = obj.Data(1:requestedCount);
        % Move up the items remaining in the buffer so that they start at
        % the first index.
        obj.Data(1:obj.Count-requestedCount) = obj.Data(requestedCount+1:obj.Count);
        % Reduce the buffer size by the number of items read.
        obj.Count = obj.Count - requestedCount;
    end
    
    function wipe(obj)
    % wipe Negate all items in the buffer.
    %
    %   This method is used to negate items held in the data buffer. Note
    %   that is does not delete the items. It sets the current count to
    %   zero, which just negates the view of the data held internally. The
    %   items are not actually cleared because we do not want the memory
    %   freed. It must be maintained.
    
        % Set the count of items in the buffer to zero.
        obj.Count = 0;
    end

end

end