# MB_ReadSegment

## Syntax

  `#include <nitro/mb.h>`
  `BOOL MB_ReadSegment(FSFile *file, void *buf, u32 len);`

## Arguments

file | The `FSFile` structure that holds the program file handle. The seek position of this file must point to the top of the program binary. Also, the seek position holds the initial position when returned from this function. When NULL is specified for this pointer, the parent application is seen as a download program file and the segment is extracted.
buf | Pointer to the memory that saves the extracted segment information.
len | Byte size of `buf`. This size must at least that of `MB_SEGMENT_BUFFER_MIN`.

## Return Values

This function returns `TRUE` when the segment data is extracted correctly from the program. Otherwise, it returns `FALSE`.

## Description

This function extracts only the segment data necessary for the download process from the specified program file. Applications must call the `MB_RegisterFile` function using the segment data obtained with this function.
When the specified buffer size is at least the value returned by the `MB_GetSegmentLength` function, calling this function prepares all segment data in memory. When the size is smaller than that returned by the `MB_GetSegmentLength` function, but at least `MB_SEGMENT_BUFFER_MIN` (as required), it is set to dynamically load the remainder that it cannot prepare in memory from the specified archive. In the case of this setting, it is frequently impossible to respond immediately to child requests, which slightly reduces transfer efficiency.
When this setting is used, a single thread will be automatically started in the MB library. For details, see the Internal Operation section.
This function fails if the size is less than `MB_SEGMENT_BUFFER_MIN`.

    Example:
        BOOL    reg_file_done = FALSE;

        FSFile file[1];
        FS_InitFile(file);
        if(FS_OpenFileEx(file, p_game_reg->romFilePathp, FS_FILEMODE_R)) {
            u32  len = MB_GetSegmentLength(file);
            if(len > 0) {
                void *mem = OS_Alloc(len);
                if(mem != NULL) {
                    if(MB_ReadSegment(file, mem, len)) {
                        if(MB_RegisterFile(p_game_reg, mem)) {
                            reg_file_done = TRUE;
                        }
                    }
                }
            }
            FS_CloseFile(file);
        }

## Internal Operation

This function calls the `FS_ReadFile` function internally.
Note that when you use segment data that is dynamically set to be read from the archive, and call the `MB_RegisterFile` function, only one internal thread is started automatically to access the archive. This thread exists until either the `MB_End` or `MB_EndToIdle` function completes. The priority of this thread is 0 and it will sleep until there is a child group request for segment data, accessing the card at irregular intervals as necessary.

## See Also

`FS_ReadFile
MB_End
MB_EndToIdle
MB_GetSegmentLength
MB_SEGMENT_BUFFER_MIN
MB_RegisterFile`

## Revision History

2008/10/02 Revised part of the sample code.
2005/04/11 Added description of task thread.
2004/12/07 Changed description because in the read delay method, the target has been extended from `NITRO-CARD` to any archive.
2004/11/11 Changed description to include the clone boot release and new read delay method.
2004/09/10 Added description of the operation when specifying NULL for the file pointer.
2004/08/09 Initial version.

CONFIDENTIAL