| 1459 | |
| 1460 | template <class SI_CHAR, class SI_STRLESS, class SI_CONVERTER> |
| 1461 | SI_Error CSimpleIniTempl<SI_CHAR, SI_STRLESS, SI_CONVERTER>::LoadData( |
| 1462 | const char *a_pData, size_t a_uDataLen) { |
| 1463 | if (!a_pData) { |
| 1464 | return SI_OK; |
| 1465 | } |
| 1466 | |
| 1467 | // if the UTF-8 BOM exists, consume it and set mode to unicode, if we have |
| 1468 | // already loaded data and try to change mode half-way through then this will |
| 1469 | // be ignored and we will assert in debug versions |
| 1470 | if (a_uDataLen >= 3 && memcmp(a_pData, SI_UTF8_SIGNATURE, 3) == 0) { |
| 1471 | a_pData += 3; |
| 1472 | a_uDataLen -= 3; |
| 1473 | SI_ASSERT(m_bStoreIsUtf8 || !m_pData); // we don't expect mixed mode data |
| 1474 | SetUnicode(); |
| 1475 | } |
| 1476 | |
| 1477 | if (a_uDataLen == 0) { |
| 1478 | return SI_OK; |
| 1479 | } |
| 1480 | |
| 1481 | // determine the length of the converted data |
| 1482 | SI_CONVERTER converter(m_bStoreIsUtf8); |
| 1483 | size_t uLen = converter.SizeFromStore(a_pData, a_uDataLen); |
| 1484 | if (uLen == (size_t)(-1)) { |
| 1485 | return SI_FAIL; |
| 1486 | } |
| 1487 | |
| 1488 | // check converted data size is within supported limits (SI_MAX_FILE_SIZE) |
| 1489 | if (uLen >= (SI_MAX_FILE_SIZE / sizeof(SI_CHAR))) { |
| 1490 | return SI_FILE; |
| 1491 | } |
| 1492 | |
| 1493 | // allocate memory for the data, ensure that there is a NULL |
| 1494 | // terminator wherever the converted data ends |
| 1495 | SI_CHAR *pData = new (std::nothrow) SI_CHAR[uLen + 1]; |
| 1496 | if (!pData) { |
| 1497 | return SI_NOMEM; |
| 1498 | } |
| 1499 | memset(pData, 0, sizeof(SI_CHAR) * (uLen + 1)); |
| 1500 | |
| 1501 | // convert the data |
| 1502 | if (!converter.ConvertFromStore(a_pData, a_uDataLen, pData, uLen)) { |
| 1503 | delete[] pData; |
| 1504 | return SI_FAIL; |
| 1505 | } |
| 1506 | |
| 1507 | // parse it |
| 1508 | const static SI_CHAR empty = 0; |
| 1509 | SI_CHAR *pWork = pData; |
| 1510 | const SI_CHAR *pSection = ∅ |
| 1511 | const SI_CHAR *pItem = NULL; |
| 1512 | const SI_CHAR *pVal = NULL; |
| 1513 | const SI_CHAR *pComment = NULL; |
| 1514 | |
| 1515 | // We copy the strings if we are loading data into this class when we |
| 1516 | // already have stored some. |
| 1517 | bool bCopyStrings = (m_pData != NULL); |
| 1518 | |