Ejemplo n.º 1
0
unsigned
LargeTextWindow::GetRowCount() const
{
    AssertNoneLocked();

    const TCHAR *str = value.c_str();
    unsigned row_count = 1;
    while ((str = StringFind(str, _T('\n'))) != nullptr) {
        str++;
        row_count++;
    }

    return row_count;
}
Ejemplo n.º 2
0
/**
 * Set up reasonable defaults for the given overlay.
 */
static void
SetupOverlay(MapOverlayBitmap &bmp, Path::const_pointer name)
{
  /* File name convention according to DWD paper:
   *
   * nb_mod_met_chart_lv_level_p_step_run
   *
   * nb = product (NinJo batch)
   * mod = model ("icon", "coseu", "cosde")
   * met = contents ("hwx", "ome", "nptw", "eis", ...)
   * chart = area
   * lb = level code
   * level = level (m or hPa)
   * p = code for predicted time
   * step = predicted time
   * run = model run [HHmm]
   */

  /* configure a default, just in case this overlay type is unknown */
  bmp.SetAlpha(0.5);

  if (StringStartsWithIgnoreCase(name, _T("nb_"))) {
    name += 3;

    /* skip "model", go to "met" */
    auto underscore = StringFind(name, '_');
    if (underscore != nullptr) {
      name = underscore + 1;

      if (StringStartsWithIgnoreCase(name, _T("ome_"))) {
        /* vertical wind */
        bmp.SetAlpha(0.5);
      } else if (StringStartsWithIgnoreCase(name, _T("w_"))) {
        /* horizontal wind */
        bmp.SetAlpha(0.7);
      }
    }
  } else if (StringStartsWithIgnoreCase(name, _T("sat_"))) {
    bmp.IgnoreBitmapAlpha();
    bmp.SetAlpha(0.9);
  } else if (StringStartsWithIgnoreCase(name, _T("pg_"))) {
    /* precipitation */
    bmp.SetAlpha(0.4);
  } else if (StringStartsWithIgnoreCase(name, _T("Vertikalwind"))) {
    /* name of a draft file I got from DWD */
    // TODO: remove obsolete prefix
    bmp.IgnoreBitmapAlpha();
    bmp.SetAlpha(0.4);
  }
}
Ejemplo n.º 3
0
static bool
parse_assignment(TCHAR *buffer, const TCHAR *&key, const TCHAR *&value)
{
  TCHAR *separator = StringFind(buffer, '=');
  if (separator == NULL || separator == buffer)
    return false;

  *separator = _T('\0');

  key = buffer;
  value = separator + 1;

  return true;
}
Ejemplo n.º 4
0
  Range Next() {
    assert(HasNext());

    const TCHAR *line_start = start;

    // Search for next line break
    const auto *line_break = StringFind(line_start, _T('\n'));
    if (!line_break) {
      // if no line break was found
      start = NULL;
      return Range(line_start, _tcslen(line_start));
    }

    unsigned length = line_break - line_start;
    start = line_break + 1;
    return Range(line_start, length);
  }
Ejemplo n.º 5
0
void
Profile::SetFiles(Path override_path)
{
  /* set the "modified" flag, because we are potentially saving to a
     new file now */
  SetModified(true);

  if (!override_path.IsNull()) {
    if (override_path.IsBase()) {
      if (StringFind(override_path.c_str(), '.') != nullptr)
        startProfileFile = LocalPath(override_path);
      else {
        tstring t(override_path.c_str());
        t += _T(".prf");
        startProfileFile = LocalPath(t.c_str());
      }
    } else
      startProfileFile = Path(override_path);
    return;
  }

  // Set the default profile file
  startProfileFile = LocalPath(_T(XCSPROFILE));
}
Ejemplo n.º 6
0
void genResponse(int cid) {
  int power = motor[motorA];
  float temp = 0.0;
  string tmpString;
  int index = 0;
  ubyte linebuff[20];
  StringFromChars(tmpString,rxbuffer);
  index = StringFind(tmpString, "/");
  StringDelete(tmpString, 0, index);
  index = StringFind(tmpString, "HTTP");
  StringDelete(tmpString, index, strlen(tmpString));
  writeDebugStreamLine("Request:%s", tmpString);
  nxtDisplayTextLine(2, "Request: ");
  nxtDisplayTextLine(3, tmpString);
  if (StringFind(tmpString, "MOTA") > 0) {
    StringDelete(tmpString, 0, 6);
    index = StringFind(tmpString, " ");
  if (index > -1)
      StringDelete(tmpString, index, strlen(tmpString));
    //power = RC_atoix(tmpString);
    power = clip(atoi(tmpString), -100, 100);
    writeDebugStreamLine("Power:%d", power);
  } else {
    writeDebugStreamLine("NO POWER: %s", tmpString);
  }

  sendHeader(cid);
  while(nxtHS_Status == HS_SENDING) wait1Msec(5);

  wait1Msec(100);

  index = 0;
  linebuff[0] = 27; // escape;
  linebuff[1] = 'S'; // the CID;
  linebuff[2] = (ubyte)cid + 48; // the CID;
  index = appendToBuff(buffer, index, linebuff, 3);
  StringFormat(tmpString, "MotorA=%d\n", power);
  memcpy(linebuff, tmpString, strlen(tmpString));
  index = appendToBuff(buffer, index, linebuff, strlen(tmpString));
  DTMPreadTemp(DTMP, temp);
  StringFormat(tmpString, "Temp: %2.2f C", temp);
  memcpy(linebuff, tmpString, strlen(tmpString));
  index = appendToBuff(buffer, index, linebuff, strlen(tmpString));
  linebuff[0] = 27; // escape;
  linebuff[1] = 'E'; // the CID;
  index = appendToBuff(buffer, index, endmarker, 2);
  writeRawHS(buffer, index);
  if (power != 0) nMotorEncoderTarget[motorA] = 2000;
  motor[motorA] = power;
  if (power > 0)
    SensorType[COLOUR] = sensorCOLORGREEN;
  else if (power < 0)
    SensorType[COLOUR] = sensorCOLORBLUE;
  else if (nMotorRunState[motorA] == runStateIdle)
    SensorType[COLOUR] = sensorCOLORRED;
  else
    SensorType[COLOUR] = sensorCOLORRED;
  wait1Msec(300);
  clear_read_buffer();
  closeConn(1);
  memset(rxbuffer, 0, sizeof(rxbuffer));
  //wait1Msec(100);
  Receive();
  //clear_read_buffer();
}
Ejemplo n.º 7
0
void
ParseInputFile(InputConfig &config, TLineReader &reader)
{
  // TODO code - Safer sizes, strings etc - use C++ (can scanf restrict length?)

  // Multiple modes (so large string)
  EventBuilder current;
  current.clear();

  int line = 0;

  // Read from the file
  TCHAR *buffer;
  while ((buffer = reader.ReadLine()) != NULL) {
    StripRight(buffer);
    line++;

    const TCHAR *key, *value;

    // experimental: if the first line is "#CLEAR" then the whole default config is cleared
    //               and can be overwritten by file
    if (line == 1 && StringIsEqual(buffer, _T("#CLEAR"))) {
      config.SetDefaults();
    } else if (buffer[0] == _T('\0')) {
      // Check valid line? If not valid, assume next record (primative, but works ok!)
      // General checks before continue...
      current.commit(config, line);

      // Clear all data.
      current.clear();

    } else if (StringIsEmpty(buffer) || buffer[0] == _T('#')) {
      // Do nothing - we probably just have a comment line
      // NOTE: Do NOT display buffer to user as it may contain an invalid stirng !

    } else if (parse_assignment(buffer, key, value)) {
      if (StringIsEqual(key, _T("mode"))) {
        current.mode = value;
      } else if (StringIsEqual(key, _T("type"))) {
        current.type = value;
      } else if (StringIsEqual(key, _T("data"))) {
        current.data = value;
      } else if (StringIsEqual(key, _T("event"))) {
        if (_tcslen(value) < 256) {
          TCHAR d_event[256] = _T("");
          TCHAR d_misc[256] = _T("");
          int ef;

          #if defined(__BORLANDC__)
          memset(d_event, 0, sizeof(d_event));
          memset(d_misc, 0, sizeof(d_event));
          if (StringFind(value, ' ') == nullptr) {
            _tcscpy(d_event, value);
          } else {
          #endif

          ef = _stscanf(value, _T("%[^ ] %[A-Za-z0-9_ \\/().,]"), d_event,
              d_misc);

          #if defined(__BORLANDC__)
          }
          #endif

          if ((ef == 1) || (ef == 2)) {

            // TODO code: Consider reusing existing identical events

            pt2Event event = InputEvents::findEvent(d_event);
            if (event) {
              TCHAR *allocated = UnescapeBackslash(d_misc);
              current.event_id = config.AppendEvent(event, allocated,
                                                    current.event_id);

              /* not freeing the string, because
                 InputConfig::AppendEvent() stores the string point
                 without duplicating it; strictly speaking, this is a
                 memory leak, but the input file is only loaded once
                 at startup, so this is acceptable; in return, we
                 don't have to duplicate the hard-coded defaults,
                 which saves some memory */
              //free(allocated);

            } else {
              LogFormat(_T("Invalid event type: %s at %i"), d_event, line);
            }
          } else {
            LogFormat("Invalid event type at %i", line);
          }
        }
      } else if (StringIsEqual(key, _T("label"))) {
        current.label = value;
      } else if (StringIsEqual(key, _T("location"))) {
        current.location = ParseUnsigned(value);

      } else {
        LogFormat(_T("Invalid key/value pair %s=%s at %i"), key, value, line);
      }
    } else  {
      LogFormat("Invalid line at %i", line);
    }

  }

  current.commit(config, line);
}
Ejemplo n.º 8
0
ButtonLabel::Expanded
ButtonLabel::Expand(const TCHAR *text, TCHAR *buffer, size_t size)
{
  Expanded expanded;
  const TCHAR *dollar;

  if (text == nullptr || *text == _T('\0') || *text == _T(' ')) {
    expanded.visible = false;
    return expanded;
  } else if ((dollar = StringFind(text, '$')) == nullptr) {
    /* no macro, we can just translate the text */
    expanded.visible = true;
    expanded.enabled = true;
    const TCHAR *nl = StringFind(text, '\n');
    if (nl != nullptr && LacksAlphaASCII(nl + 1)) {
      /* Quick hack for skipping the translation for second line of a two line
         label with only digits and punctuation in the second line, e.g.
         for menu labels like "Config\n2/3" */

      /* copy the text up to the '\n' to a new buffer and translate it */
      TCHAR translatable[256];
      const TCHAR *translated = GetTextN(text, nl, translatable,
                                         ARRAY_SIZE(translatable));
      if (translated == nullptr) {
        /* buffer too small: keep it untranslated */
        expanded.text = text;
        return expanded;
      }

      /* concatenate the translated text and the part starting with '\n' */
      expanded.text = BuildString(buffer, size, translated, nl);
    } else
      expanded.text = gettext(text);
    return expanded;
  } else {
    const TCHAR *macros = dollar;
    /* backtrack until the first non-whitespace character, because we
       don't want to translate whitespace between the text and the
       macro */
    macros = StripRight(text, macros);

    TCHAR s[100];
    expanded.enabled = !ExpandMacros(text, s, ARRAY_SIZE(s));
    if (s[0] == _T('\0') || s[0] == _T(' ')) {
      expanded.visible = false;
      return expanded;
    }

    /* copy the text (without trailing whitespace) to a new buffer and
       translate it */
    TCHAR translatable[256];
    const TCHAR *translated = GetTextN(text, macros, translatable,
                                       ARRAY_SIZE(translatable));
    if (translated == nullptr) {
      /* buffer too small: fail */
      // TODO: find a more clever fallback
      expanded.visible = false;
      return expanded;
    }

    /* concatenate the translated text and the macro output */
    expanded.visible = true;
    expanded.text = BuildString(buffer, size, translated, s + (macros - text));
    return expanded;
  }
}
Ejemplo n.º 9
0
const char *Pxf::StringFindI(const char *target, const char find)
{
	if(tolower(find) == toupper(find))
		return StringFind(target, find);
	return StringFind2(target, tolower(find), toupper(find));
}
Ejemplo n.º 10
0
int StringFindTest()
{
	{
		test_assert( StringFind( "::", std::string() ) == std::string::npos );
		test_assert( StringFind( "ab", "a b" ) == std::string::npos );
		test_assert( StringFind( "ab", "aabb" ) == 1 );
		test_assert( StringFind( "ab", "\"aabb" ) == std::string::npos );
		test_assert( StringFind( "ab", "aabb\"" ) == 1 );

		std::string test = "\"abcdefghiklmopqrstuvxyzåäö\"";
		test_assert( StringFind( "a", test ) == std::string::npos );
		test_assert( StringFind( "b", test ) == std::string::npos );
		test_assert( StringFind( "c", test ) == std::string::npos );
		test_assert( StringFind( "d", test ) == std::string::npos );
		test_assert( StringFind( "e", test ) == std::string::npos );
		test_assert( StringFind( "f", test ) == std::string::npos );
		test_assert( StringFind( "g", test ) == std::string::npos );
		test_assert( StringFind( "h", test ) == std::string::npos );
		test_assert( StringFind( "i", test ) == std::string::npos );
		test_assert( StringFind( "j", test ) == std::string::npos );
		test_assert( StringFind( "k", test ) == std::string::npos );
		test_assert( StringFind( "l", test ) == std::string::npos );
		test_assert( StringFind( "m", test ) == std::string::npos );
		test_assert( StringFind( "n", test ) == std::string::npos );
		test_assert( StringFind( "o", test ) == std::string::npos );
		test_assert( StringFind( "p", test ) == std::string::npos );
		test_assert( StringFind( "q", test ) == std::string::npos );
		test_assert( StringFind( "r", test ) == std::string::npos );
		test_assert( StringFind( "s", test ) == std::string::npos );
		test_assert( StringFind( "t", test ) == std::string::npos );
		test_assert( StringFind( "u", test ) == std::string::npos );
		test_assert( StringFind( "v", test ) == std::string::npos );
		test_assert( StringFind( "x", test ) == std::string::npos );
		test_assert( StringFind( "y", test ) == std::string::npos );
		test_assert( StringFind( "z", test ) == std::string::npos );
		test_assert( StringFind( "å", test ) == std::string::npos );
		test_assert( StringFind( "ä", test ) == std::string::npos );
		test_assert( StringFind( "ö", test ) == std::string::npos );

	}

	{
		test_assert( StringFindFirstOf( "::", std::string() ) == std::string::npos );
		test_assert( StringFindFirstOf( "ab", "a b" ) != std::string::npos );
		test_assert( StringFindFirstOf( "ab", "a b" ) == 0 );
		test_assert( StringFindFirstOf( "ab", "aabb" ) == 0 );

		test_assert( StringFindFirstOf( "ab", "\"aabb" ) == std::string::npos );
		test_assert( StringFindFirstOf( "ab", "aabb\"" ) == 0 );

		std::string test = "\"abcdefghiklmopqrstuvxyzåäö\"";
		test_assert( StringFindFirstOf( "abcdefghijklmonpqrstuvxyzåäö", test ) == std::string::npos );
		test_assert( StringFindFirstOf( "\"", test ) == 0 );
	}
	return 0;
}
void OpenSMOKE_CHEMKINInterpreter_ThermoData::ReadThermoData(const std::string file_name, ofstream *_fLog)
{
	const int SIZE = 400;
	char comment[SIZE];

	fLog = _fLog;

	ifstream fInput;
	openInputFileAndControl(fInput, file_name);

	// ---------------------------------------------------------------
	// Reading lines
	// ---------------------------------------------------------------
	lines.push_back("List of lines");

	while(!fInput.eof())
	{
		fInput.getline(comment, SIZE);
		lines.push_back(comment);
	}
	fInput.close();

	number_of_lines = lines.size()-1;

	// ---------------------------------------------------------------
	// Parsing lines
	// ---------------------------------------------------------------
	int i;
	for(i=1;i<=number_of_lines;i++)
	{
		if (CheckForBlankLine(lines[i]) == true)		indexBlankLines.Append(i);
		else if (CheckForCommentLine(lines[i]) == true)	indexCommentLines.Append(i);
		else if (CheckForEndLine(lines[i]) == true)		indexCommentLines.Append(i);		
		else											indexLines.Append(i);
	}

	int count_additional=0;
	for(i=1;i<=indexLines.Size();i++)
		count_additional += StringFind(lines[indexLines[i]], "1&");
	total_number_of_species = (indexLines.Size()-count_additional)/4;

	*fLog << " ----------------------------------------------------------------" << endl;
	*fLog << "                     Thermodynamic Database                      " << endl;
	*fLog << " ----------------------------------------------------------------" << endl;
	*fLog << "    Total number of full lines:    " << indexLines.Size()			<< endl;
	*fLog << "    Total number of blank lines:   " << indexBlankLines.Size()		<< endl;
	*fLog << "    Total number of comment lines: " << indexCommentLines.Size()	<< endl;
	*fLog << "    Total number of lines:         " << number_of_lines			<< endl;
	*fLog << "    Total number of species:       " << total_number_of_species			<< endl;
	*fLog << " ----------------------------------------------------------------" << endl;

	species = new OpenSMOKE_CHEMKINInterpreter_ThermoSpecies[total_number_of_species+1];
	
	vector<string> instructions;
	
	// ---------------------------------------------------------------
	// First line
	// ---------------------------------------------------------------
	SeparateInstructions(lines[indexLines[1]], instructions);
	if (instructions.size()-1 > 2)		ErrorMessage("Too many arguments in the first line");
	if (instructions[1] != "THERMO")	ErrorMessage("Expected: THERMO - Found: " + instructions[1]);
	if (instructions.size()-1 == 2)
		if (instructions[2] != "ALL")	ErrorMessage("Expected: ALL - Found: " + instructions[2]);

	// ---------------------------------------------------------------
	// Second line
	// ---------------------------------------------------------------
	SeparateInstructions(lines[indexLines[2]], instructions);
	if (instructions.size()-1 != 3)		ErrorMessage("Too many arguments in the second line");
	tmin  = atof(instructions[1].c_str());
	tmean = atof(instructions[2].c_str());
	tmax  = atof(instructions[3].c_str());

	int j=3;
	for(i=1;i<=total_number_of_species;i++)
	{
		species[i].AssignTemperatures(tmin, tmean, tmax);
		species[i].ReadMainData(lines[indexLines[j]], indexLines[j]);	j++;
		if (species[i].iContinuation==true)
		{	
			species[i].ReadAdditionalLine(lines[indexLines[j]]);		j++;
		}
		species[i].ReadFirstLine(lines[indexLines[j]]);					j++;
		species[i].ReadSecondLine(lines[indexLines[j]]);				j++;
		species[i].ReadThirdLine(lines[indexLines[j]]);					j++;

		species[i].Analyze();
	}
}
Ejemplo n.º 12
0
ButtonLabel::Expanded
ButtonLabel::Expand(const TCHAR *text, TCHAR *buffer, size_t size)
{
  Expanded expanded;
  const TCHAR *dollar;

  if ((text == nullptr) || (*text == _T('\0')) || (*text == _T(' '))) {
    expanded.visible = false;
    return expanded;
  } else if ((dollar = StringFind(text, '$')) == nullptr) {
    /* no macro, we can just translate the text */
    expanded.visible = true;
    expanded.enabled = true;
    const TCHAR *nl;
    if (((nl = StringFind(text, '\n')) != nullptr) &&
        LacksAlphaASCII(nl + 1)) {
      /* Quick hack for skipping the translation for second line of a two line
         label with only digits and punctuation in the second line, e.g.
         for menu labels like "Config\n2/3" */

      /* copy the text up to the '\n' to a new buffer and translate it */
      TCHAR translatable[256];
      std::copy(text, nl, translatable);
      translatable[nl - text] = _T('\0');

      const TCHAR *translated = StringIsEmpty(translatable)
        ? _T("") : gettext(translatable);

      /* concatenate the translated text and the part starting with '\n' */
      _tcscpy(buffer, translated);
      _tcscat(buffer, nl);

      expanded.text = buffer;
    } else
      expanded.text = gettext(text);
    return expanded;
  } else {
    const TCHAR *macros = dollar;
    /* backtrack until the first non-whitespace character, because we
       don't want to translate whitespace between the text and the
       macro */
    macros = StripRight(text, macros);

    TCHAR s[100];
    expanded.enabled = !ExpandMacros(text, s, ARRAY_SIZE(s));
    if (s[0] == _T('\0') || s[0] == _T(' ')) {
      expanded.visible = false;
      return expanded;
    }

    /* copy the text (without trailing whitespace) to a new buffer and
       translate it */
    TCHAR translatable[256];
    std::copy(text, macros, translatable);
    translatable[macros - text] = _T('\0');

    const TCHAR *translated = StringIsEmpty(translatable)
      ? _T("") : gettext(translatable);

    /* concatenate the translated text and the macro output */
    _tcscpy(buffer, translated);
    _tcscat(buffer, s + (macros - text));

    expanded.visible = true;
    expanded.text = buffer;
    return expanded;
  }
}
Ejemplo n.º 13
0
void
GlueMapWindow::DrawPanInfo(Canvas &canvas) const
{
  if (!render_projection.IsValid())
    return;

  GeoPoint location = render_projection.GetGeoLocation();

  TextInBoxMode mode;
  mode.shape = LabelShape::OUTLINED;
  mode.align = TextInBoxMode::Alignment::RIGHT;

  const Font &font = *look.overlay.overlay_font;
  canvas.Select(font);

  unsigned padding = Layout::FastScale(4);
  unsigned height = font.GetHeight();
  int y = 0 + padding;
  int x = render_projection.GetScreenWidth() - padding;

  if (compass_visible)
    /* don't obscure the north arrow */
    /* TODO: obtain offset from CompassRenderer */
    y += Layout::Scale(19) + Layout::FastScale(13);

  if (terrain) {
    TerrainHeight elevation = terrain->GetTerrainHeight(location);
    if (!elevation.IsSpecial()) {
      StaticString<64> elevation_long;
      elevation_long = _("Elevation: ");
      elevation_long += FormatUserAltitude(elevation.GetValue());

      TextInBox(canvas, elevation_long, x, y, mode,
                render_projection.GetScreenWidth(),
                render_projection.GetScreenHeight());

      y += height;
    }
  }

  TCHAR buffer[256];
  FormatGeoPoint(location, buffer, ARRAY_SIZE(buffer), _T('\n'));

  TCHAR *start = buffer;
  while (true) {
    auto *newline = StringFind(start, _T('\n'));
    if (newline != nullptr)
      *newline = _T('\0');

    TextInBox(canvas, start, x, y, mode,
              render_projection.GetScreenWidth(),
              render_projection.GetScreenHeight());

    y += height;

    if (newline == nullptr)
      break;

    start = newline + 1;
  }
}
Ejemplo n.º 14
0
 gcc_pure
 bool Contains(const T *needle) const {
   return StringFind(data, needle) != NULL;
 }
Ejemplo n.º 15
0
 gcc_pure
 bool Contains(const_pointer needle) const {
   return StringFind(data, needle) != nullptr;
 }
Ejemplo n.º 16
0
Archivo: sub.c Proyecto: QGB/QCSU
char* sub( char* ast,char* asa,char* asb){
	int ia=-1,ib=-1,iam=0,ibm=0,im=0;
	//printf("t=[%s],a=[%s],b=[%s]",ast,asa,asb);
	 iam=strlen(asa);
	 ibm=strlen(asb);
	 im=strlen(ast);

	if (im==0)
		return "";

	if (iam==0&&ibm==0)
		return "";

	char* sd=(char *)malloc(im*sizeof(char));
	int i=0;
	for (i=0;i<im;i++)
		sd[i]='\0';

	if (iam==0)
	{
		ib=StringFind(ast,asb);
		if (ib==-1)
			return "";

		memcpy(sd,ast,ib);
		return sd;
	}


	if (ibm==0)
	{
		ia=StringFind(ast,asa);
		if (ia==-1)
			return "";
		ia=ia+iam;
		memcpy(sd,ast+ia,im);
		return sd;
	}


	if (NULL !=strstr(asa,asb))
		return "";

	ia=StringFind(ast,asa)+iam;

	im=im-ia;
	if (0==im||-1==ia)
		return "";


	memcpy(sd,ast+ia,im);

	char* sdb=(char *)malloc(im*sizeof(char));
	for (i=0;i<im;i++)
		sdb[i]='\0';

	ib=StringFind(sd,asb);
	if (ib==-1)
		return "";
	memcpy(sdb,sd,ib);

	return sdb;
}
Ejemplo n.º 17
0
Archivo: Bds.c Proyecto: hzhuang1/uefi
EFI_STATUS
GetBootDeviceTypeInfo (
  VOID
  )
{
    EFI_STATUS        Status = EFI_SUCCESS;
    LIST_ENTRY        BootOptionsList;
    LIST_ENTRY*       Entry;    
    UINT16            *SataDes = NULL;
    UINT16            *MacDes = NULL;
    UINTN             SataDesSize = 0;
    UINTN             MacDesSize = 0; 
    BDS_LOAD_OPTION*  BootOption;
    UINTN             OptionCount = 0;
    CHAR16*           SataStr = L"Sata";
    CHAR16*           MacStr = L"MAC";
    CHAR16*           DevicePathTxt = NULL;
    EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol = NULL;    
    
    // Get Boot#### list
    BootOptionList (&BootOptionsList);
    // Display the Boot options
    for (Entry = GetFirstNode (&BootOptionsList);
     !IsNull (&BootOptionsList,Entry);
     Entry = GetNextNode (&BootOptionsList,Entry)
     )
    {
        BootOption = LOAD_OPTION_FROM_LINK(Entry);
        //Print(L"[%d] %s\n", OptionCount, BootOption->Description);
        //DEBUG_CODE_BEGIN();
        Status = gBS->LocateProtocol (&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
        if (EFI_ERROR(Status)) {
            // You must provide an implementation of DevicePathToTextProtocol in your firmware (eg: DevicePathDxe)
            DEBUG((EFI_D_ERROR,"Error: Bds requires DevicePathToTextProtocol\n"));
            return Status;
        }
        DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (BootOption->FilePathList, TRUE, TRUE);
         //Print(L"\t- %s\n",DevicePathTxt);
        //DEBUG_CODE_END();        
         //FIND SATA BOOT DEVICES       
        if(!(StringFind(DevicePathTxt, SataStr)))
        {                        
            if(SataDesSize != 0)
            {
                SataDes = ReallocatePool (SataDesSize, SataDesSize + sizeof(UINT16), SataDes);
                SataDes[SataDesSize / sizeof(UINT16)] = BootOption->LoadOptionIndex;
                SataDesSize += sizeof(UINT16);
            }else{
                SataDesSize = sizeof(UINT16);
                SataDes = &(BootOption->LoadOptionIndex);
            }
           // Print(L"liuhuan SATA boot num: %d\n",SataDesSize / sizeof(UINT16));
        }        
        //FIND PXE BOOT DEVICES
        if(!(StringFind(DevicePathTxt, MacStr) ))            
        {                        
            if(MacDesSize != 0)
            {
                MacDes = ReallocatePool (MacDesSize, MacDesSize + sizeof(UINT16), MacDes);
                MacDes[MacDesSize / sizeof(UINT16)] = BootOption->LoadOptionIndex;
                MacDesSize += sizeof(UINT16);
            }else{
                MacDesSize = sizeof(UINT16);
                MacDes = &(BootOption->LoadOptionIndex);
            }
         //   Print(L"liuhuan PXE boot num: %d\n",MacDesSize / sizeof(UINT16));
        }
        //FreePool(DevicePathTxt);    
        OptionCount++;
    }
     
    OemGetSataBootNum(SataDesSize);
    OemGetPXEBootNum(MacDesSize);

    if(SataDes != NULL)
    {
        FreePool(SataDes);
    }
    if(MacDes != NULL)
    {
        FreePool(MacDes);
    }
    if(DevicePathTxt != NULL)
    {
        FreePool(DevicePathTxt);
    }
    return EFI_SUCCESS;
}