Skocz do zawartości

Biblioteka SDFat - polskie znaki w nazwach plików


Pomocna odpowiedź

6 minut temu, ElektronPL_WiTu napisał:

dobra mam już coś - małe ó w utf-16 to 243 - mieści się w bajcie

Nie tylko w UTF-16 (a właściwie UCS-2, to niezupełnie to samo, zacznij odróżniać), ale np. w CP1252 też.

12 minut temu, ElektronPL_WiTu napisał:

fname_t* fname przechowuje znaki w bajtach czy 16 bitowych znakach?

A co, pliki nagłówkowe Ci ktoś ukradł???

struct fname_t {
  /** Flags for base and extension character case and LFN. */
  uint8_t flags;
  /** length of Long File Name */
  size_t len;
  /** Long File Name start. */
  const char* lfn;
  /** position for sequence number */
  uint8_t seqPos;
  /** Short File Name */
  uint8_t sfn[11];
};

 

Poczekaj, coś mi wpadło do głowy (nie mam żadnego czytnika kart więc nie sprawdzę):

czy 'ł' to nie będzie przypadkiem 0xb3 (ósemkowo \263)?

5 minut temu, ElektronPL_WiTu napisał:

w funkcji open napisać kod który skonwertuje w locie kody

Nie w open tylko w funkcji, która znajduje powiązanie LFN-SFN!

no tak ł to jest (DEC) 179 ale w UTF-8. ł w nazwie pliku jest odczytywane jako (DEC) 322 a to się w bajcie nie mieści. I jak podaje mu \263 to nie znajduje bo on żeby znaleźć to bym musiał mu napisać \502, ale to jest niemożliwe.

Jeszcze jedna możliwość - 'ł' to 0x42 czyli \102 - jeśli tak, to może być nieciekawie.

Przed chwilą, ElektronPL_WiTu napisał:

ale w UTF-8.

Ja nie pytałem o UTF-8, nie musisz mi tłumaczyć co to jest. Podałem dwie możliwości zapisu litery 'ł', może więc napiszesz jasno i wyraźnie czy któraś z tych możliwości jest prawdziwa.

(edytowany)

no nie. jeśli bym do bajtu zapisał 322 to w binarce dostane coś takiego 101000010 tylko że to jest 9 bitów więc ostatni znak zostanie obcięty, wyjdzie wtedy 01000010 a to jest 'B'. więc żeby to działało trzeba by przechowywać w stringu 'ł' jako 0xb3 potem już w bibliotece zamienić sobie to na te 322.

Edytowano przez ElektronPL_WiTu

Dobra działa. Testowo w funkcji open zrobiłem coś takiego:

size_t k = 13*(ord - 1);
      if (k >= len) {
        // Not found.
        lfnOrd = 0;
        continue;
      }
      for (uint8_t i = 0; i < 13; i++) {
        uint16_t u = lfnGetChar(ldir, i);
		if(u==263)      u = 230; // ć
		else if(u==322) u = 179; // ł
		else if(u==347) u = 156; // ś
		else if(u==243) u = 243; // ó
		else if(u==261) u = 185; // ą
		else if(u==281) u = 234; // ę
		else if(u==378) u = 159; // ź
		else if(u==380) u = 191; // ż
		else if(u==324) u = 241; // ń
		
		else if(u==262) u = 198; // Ć
		else if(u==321) u = 163; // Ł
		else if(u==346) u = 140; // Ś
		else if(u==211) u = 211; // Ó
		else if(u==260) u = 165; // Ą
		else if(u==280) u = 202; // Ę
		else if(u==377) u = 143; // Ź
		else if(u==379) u = 175; // Ż
		else if(u==323) u = 209; // Ń
		
        if (k == len) {
          if (u != 0) {
            // Not found.
            lfnOrd = 0;
          }
          break;
        }
        if (u > 255 || lfnToLower(u) != lfnToLower(fname->lfn[k++])) {
          // Not found.
          lfnOrd = 0;
          break;
        }
      }

I teraz działają wszystkie pliki i foldery (lfn i sfn)

(edytowany)

To dobry pomysł, zaraz zmienię, dzięki 🙂

EDIT: Poprawiłem, działa.

static uint16_t lfnGetChar(ldir_t *ldir, uint8_t i) {
  uint16_t ret=0;
  if (i < LDIR_NAME1_DIM) {
    ret = ldir->name1[i];
  } else if (i < (LDIR_NAME1_DIM + LDIR_NAME2_DIM)) {
    ret = ldir->name2[i - LDIR_NAME1_DIM];
  } else if (i < (LDIR_NAME1_DIM + LDIR_NAME2_DIM + LDIR_NAME2_DIM)) {
    ret = ldir->name3[i - LDIR_NAME1_DIM - LDIR_NAME2_DIM];
  }
  
  if(ret==263)      ret = 230; // ć
  else if(ret==322) ret = 179; // ł
  else if(ret==347) ret = 156; // ś
  else if(ret==243) ret = 243; // ó
  else if(ret==261) ret = 185; // ą
  else if(ret==281) ret = 234; // ę
  else if(ret==378) ret = 159; // ź
  else if(ret==380) ret = 191; // ż
  else if(ret==324) ret = 241; // ń
		
  else if(ret==262) ret = 198; // Ć
  else if(ret==321) ret = 163; // Ł
  else if(ret==346) ret = 140; // Ś
  else if(ret==211) ret = 211; // Ó
  else if(ret==260) ret = 165; // Ą
  else if(ret==280) ret = 202; // Ę
  else if(ret==377) ret = 143; // Ź
  else if(ret==379) ret = 175; // Ż
  else if(ret==323) ret = 209; // Ń
  
  return ret;
}

 

Edytowano przez ElektronPL_WiTu
(edytowany)

Jednak pojawił się kolejny problem. Gdy plik nie istnieje a ja wywołam funkcje open i chce zapisać plik. (W takiej sytuacji zostaje on utworzony) to pojawia się problem. Zaraz będę diagnozować co się dokładniej dzieje, ale jakieś sugestie będą na pewno pomocne. Na razie zmodyfikowałem funkcje lfnPutChar żeby działała odwrotnie do getChar ale to nie pomogło.

static void lfnPutChar(ldir_t *ldir, uint8_t i, uint16_t c) {
  if(c==230)      c = 263; // ć
  else if(c==179) c = 322; // ł
  else if(c==156) c = 347; // ś
  else if(c==243) c = 243; // ó
  else if(c==185) c = 261; // ą
  else if(c==234) c = 281; // ę
  else if(c==159) c = 378; // ź
  else if(c==191) c = 380; // ż
  else if(c==241) c = 324; // ń
		
  else if(c==198) c = 262; // Ć
  else if(c==163) c = 321; // Ł
  else if(c==140) c = 346; // Ś
  else if(c==211) c = 211; // Ó
  else if(c==165) c = 260; // Ą
  else if(c==202) c = 280; // Ę
  else if(c==143) c = 377; // Ź
  else if(c==175) c = 379; // Ż
  else if(c==209) c = 323; // Ń
  
  if (i < LDIR_NAME1_DIM) {
    ldir->name1[i] = c;
  } else if (i < (LDIR_NAME1_DIM + LDIR_NAME2_DIM)) {
    ldir->name2[i - LDIR_NAME1_DIM] = c;
  } else if (i < (LDIR_NAME1_DIM + LDIR_NAME2_DIM + LDIR_NAME2_DIM)) {
    ldir->name3[i - LDIR_NAME1_DIM - LDIR_NAME2_DIM] = c;
  }
}

 

Edytowano przez ElektronPL_WiTu

dobra mam pewną poszlakę. Sprawdziłem co się zapisało gdy fname wyglądał tak: "\263.txt" czyli "ł.txt" no i ł zostało zapsiane jako numer 65459. I teraz istotna sprawa - (DEC) 179 to 'ł' tylko że dla signed byte 179 to jest -77. A 65459 to jest właśnie -77 tylko w 16 bitowym słowie.

I tu może być problem - bo (nie bardzo mam teraz czas zaglądać w kod) wydaje mi się, cała ta biblioteka radośnie zakłada że wszyscy na świecie gadają po angielsku, niemiecku, francusku albo hiszpańsku... i w związku z tym operuje na CP1252 - co jest bardzo wygodne szczególnioe dla leni, bo po kody z 1252 (aka ISO1) w interesującym zakresie pokrywają się z Unikodem. I o ile można oszukać metodę wyszukująca plik podstawiając inne ośmiobitowe kody, o tyle do utworzenia pliku to nie wystarczy bo musisz operować przynajmniej w zakresie do 0x17f. I to nie w funkcji open.

Pytanie kontrolne:

Czy jeśli użyjesz biblioteki bez modyfikacji, i będziesz operować znakami z zakresu CP-1252, wszystko będzie działać prawidłowo? Czy np. nazwa "el_niño.txt" będzie zapisana prawidłowo? A co się stanie, jeśli utworzysz plik o nazwie "rączka.txt"? Również bez modyfikacji.

 

ok no działa tylko nie podoba mi się to rozwiązanie. (przykład tylko dla ł w putChar)

 else if(c==65459) c = 322; // ł

czy mogę jakoś zrobić żeby przy tworzeniu pliku te wartości były "normalne"? tj zamiast 65459 (czyli -77) po prostu 179...

Gdzieś w programie powinno być "unsigned char" zamiast "char" - teraz tylko poszukać...

A, i dodatkowe pytanie: na jakiej platformie to robisz? Bo jeśli małe Arduino to może wyjść co najwyżej jakaś proteza, ale jeśli coś większego (ESP na przykład) to pewnie można w ogóle przejść na wchar_t zamiast char.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...