1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903 |
- /* abcio.cpp
- *
- * Copyright (C) 1992-2011,2015,2017,2018 Paul Boersma
- *
- * This code is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This code is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this work. If not, see <http://www.gnu.org/licenses/>.
- */
- /*
- * pb 2002/03/07 GPL
- * pb 2003/05/19 accept percent signs in getReal
- * pb 2004/10/01 Melder_double instead of %.17g
- * pb 2006/02/17 support for Intel-based Macs
- * pb 2006/02/20 corrected bingeti3, bingeti3LE, binputi3, binputi3LE
- * pb 2006/03/28 support for systems where a long is not 32 bits and a short is not 16 bits
- * pb 2007/07/21 MelderReadString
- * pb 2007/08/14 check for null pointer before Melder_isValidAscii
- * pb 2009/03/18 modern enums
- * fb 2010/02/26 UTF-16 via bin(get|put)utf16()
- * pb 2010/03/09 more support for Unicode values above 0xFFFF
- * pb 2010/12/23 corrected bingeti3 and bingeti3LE for 64-bit systems
- * pb 2011/03/30 C++
- */
- #include "melder.h"
- #include <ctype.h>
- #ifdef macintosh
- #include <TargetConditionals.h>
- #endif
- /********** text I/O **********/
- static int64 getInteger (MelderReadText me) {
- char buffer [41];
- char32 c;
- /*
- * Look for the first numeric character.
- */
- for (c = MelderReadText_getChar (me); c != U'-' && ! Melder_isAsciiDecimalNumber (c) && c != U'+'; c = MelderReadText_getChar (me)) {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected while looking for an integer (line ", MelderReadText_getLineNumber (me), U").");
- if (c == U'!') { // end-of-line comment?
- while ((c = MelderReadText_getChar (me)) != U'\n' && c != U'\r') {
- if (c == 0)
- Melder_throw (U"Early end of text detected in comment while looking for an integer (line ", MelderReadText_getLineNumber (me), U").");
- }
- }
- if (c == U'\"')
- Melder_throw (U"Found a string while looking for an integer in text (line ", MelderReadText_getLineNumber (me), U").");
- if (c == U'<')
- Melder_throw (U"Found an enumerated value while looking for an integer in text (line ", MelderReadText_getLineNumber (me), U").");
- while (! Melder_isHorizontalOrVerticalSpace (c)) {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected in comment (line ", MelderReadText_getLineNumber (me), U").");
- c = MelderReadText_getChar (me);
- }
- }
- int i = 0;
- for (; i < 40; i ++) {
- if (c > 127)
- Melder_throw (U"Found strange text while looking for an integer in text (line ", MelderReadText_getLineNumber (me), U").");
- buffer [i] = (char) (char8) c; // guarded conversion down
- c = MelderReadText_getChar (me);
- if (c == U'\0') { break; } // this may well be OK here
- if (Melder_isHorizontalOrVerticalSpace (c)) break;
- }
- if (i >= 40)
- Melder_throw (U"Found long text while looking for an integer in text (line ", MelderReadText_getLineNumber (me), U").");
- buffer [i + 1] = '\0';
- return strtoll (buffer, nullptr, 10);
- }
- static uint64 getUnsigned (MelderReadText me) {
- char buffer [41];
- char32 c;
- for (c = MelderReadText_getChar (me); ! Melder_isAsciiDecimalNumber (c) && c != U'+'; c = MelderReadText_getChar (me)) {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected while looking for an unsigned integer (line ", MelderReadText_getLineNumber (me), U").");
- if (c == U'!') { // end-of-line comment?
- while ((c = MelderReadText_getChar (me)) != '\n' && c != '\r') {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected in comment while looking for an unsigned integer (line ", MelderReadText_getLineNumber (me), U").");
- }
- }
- if (c == U'\"')
- Melder_throw (U"Found a string while looking for an unsigned integer in text (line ", MelderReadText_getLineNumber (me), U").");
- if (c == U'<')
- Melder_throw (U"Found an enumerated value while looking for an unsigned integer in text (line ", MelderReadText_getLineNumber (me), U").");
- if (c == U'-')
- Melder_throw (U"Found a negative value while looking for an unsigned integer in text (line ", MelderReadText_getLineNumber (me), U").");
- while (! Melder_isHorizontalOrVerticalSpace (c)) {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected in comment (line ", MelderReadText_getLineNumber (me), U").");
- c = MelderReadText_getChar (me);
- }
- }
- int i = 0;
- for (i = 0; i < 40; i ++) {
- if (c > 127)
- Melder_throw (U"Found strange text while looking for an unsigned integer in text (line ", MelderReadText_getLineNumber (me), U").");
- buffer [i] = (char) (char8) c; // guarded conversion down
- c = MelderReadText_getChar (me);
- if (c == U'\0') { break; } // this may well be OK here
- if (Melder_isHorizontalOrVerticalSpace (c)) break;
- }
- if (i >= 40)
- Melder_throw (U"Found long text while searching for an unsigned integer in text (line ", MelderReadText_getLineNumber (me), U").");
- buffer [i + 1] = '\0';
- return strtoull (buffer, nullptr, 10);
- }
- static double getReal (MelderReadText me) {
- int i;
- char buffer [41], *slash;
- char32 c;
- do {
- for (c = MelderReadText_getChar (me); c != U'-' && ! Melder_isAsciiDecimalNumber (c) && c != U'+'; c = MelderReadText_getChar (me)) {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected while looking for a real number (line ", MelderReadText_getLineNumber (me), U").");
- if (c == U'!') { // end-of-line comment?
- while ((c = MelderReadText_getChar (me)) != U'\n' && c != U'\r') {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected in comment while looking for a real number (line ", MelderReadText_getLineNumber (me), U").");
- }
- }
- if (c == U'\"')
- Melder_throw (U"Found a string while looking for a real number in text (line ", MelderReadText_getLineNumber (me), U").");
- if (c == U'<')
- Melder_throw (U"Found an enumerated value while looking for a real number in text (line ", MelderReadText_getLineNumber (me), U").");
- while (! Melder_isHorizontalOrVerticalSpace (c)) {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected in comment while looking for a real number (line ", MelderReadText_getLineNumber (me), U").");
- c = MelderReadText_getChar (me);
- }
- }
- for (i = 0; i < 40; i ++) {
- if (c > 127)
- Melder_throw (U"Found strange text while looking for a real number in text (line ", MelderReadText_getLineNumber (me), U").");
- buffer [i] = (char) (char8) c; // guarded conversion down
- c = MelderReadText_getChar (me);
- if (c == U'\0') { break; } // this may well be OK here
- if (Melder_isHorizontalOrVerticalSpace (c)) break;
- }
- if (i >= 40)
- Melder_throw (U"Found long text while searching for a real number in text (line ", MelderReadText_getLineNumber (me), U").");
- } while (i == 0 && buffer [0] == '+'); // guard against single '+' symbols, which occur in complex numbers
- buffer [i + 1] = '\0';
- slash = strchr (buffer, '/');
- if (slash) {
- double numerator, denominator;
- *slash = '\0';
- numerator = Melder_a8tof (buffer), denominator = Melder_a8tof (slash + 1);
- if (isundef (numerator) || isundef (denominator) || denominator == 0.0)
- return undefined;
- return numerator / denominator;
- }
- return Melder_a8tof (buffer);
- }
- static int getEnum (MelderReadText me, int (*getValue) (conststring32)) {
- char32 buffer [41], c;
- for (c = MelderReadText_getChar (me); c != U'<'; c = MelderReadText_getChar (me)) {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected while looking for an enumerated value (line ", MelderReadText_getLineNumber (me), U").");
- if (c == U'!') { /* End-of-line comment? */
- while ((c = MelderReadText_getChar (me)) != U'\n' && c != U'\r') {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected in comment while looking for an enumerated value (line ", MelderReadText_getLineNumber (me), U").");
- }
- }
- if (c == U'-' || Melder_isAsciiDecimalNumber (c) || c == U'+')
- Melder_throw (U"Found a number while looking for an enumerated value in text (line ", MelderReadText_getLineNumber (me), U").");
- if (c == U'\"')
- Melder_throw (U"Found a string while looking for an enumerated value in text (line ", MelderReadText_getLineNumber (me), U").");
- while (! Melder_isHorizontalOrVerticalSpace (c)) {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected in comment while looking for an enumerated value (line ", MelderReadText_getLineNumber (me), U").");
- c = MelderReadText_getChar (me);
- }
- }
- int i = 0;
- for (; i < 40; i ++) {
- c = MelderReadText_getChar (me); // read past first '<'
- if (c == U'\0')
- Melder_throw (U"Early end of text detected while reading an enumerated value (line ", MelderReadText_getLineNumber (me), U").");
- if (Melder_isHorizontalOrVerticalSpace (c))
- Melder_throw (U"No matching '>' while reading an enumerated value (line ", MelderReadText_getLineNumber (me), U").");
- if (c == U'>')
- break; // the expected closing bracket; not added to the buffer
- buffer [i] = c;
- }
- if (i >= 40)
- Melder_throw (U"Found strange text while reading an enumerated value in text (line ", MelderReadText_getLineNumber (me), U").");
- buffer [i] = U'\0';
- int value = getValue (buffer);
- if (value < 0)
- Melder_throw (U"\"", buffer, U"\" is not a value of the enumerated type.");
- return value;
- }
- static char32 * peekString (MelderReadText me) {
- static MelderString buffer { };
- MelderString_empty (& buffer);
- for (char32 c = MelderReadText_getChar (me); c != U'\"'; c = MelderReadText_getChar (me)) {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected while looking for a string (line ", MelderReadText_getLineNumber (me), U").");
- if (c == U'!') { // end-of-line comment?
- while ((c = MelderReadText_getChar (me)) != '\n' && c != '\r') {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected in comment while looking for a string (line ", MelderReadText_getLineNumber (me), U").");
- }
- }
- if (c == U'-' || Melder_isAsciiDecimalNumber (c) || c == U'+')
- Melder_throw (U"Found a number while looking for a string in text (line ", MelderReadText_getLineNumber (me), U").");
- if (c == U'<')
- Melder_throw (U"Found an enumerated value while looking for a string in text (line ", MelderReadText_getLineNumber (me), U").");
- while (! Melder_isHorizontalOrVerticalSpace (c)) {
- if (c == U'\0')
- Melder_throw (U"Early end of text detected while looking for a string (line ", MelderReadText_getLineNumber (me), U").");
- c = MelderReadText_getChar (me);
- }
- }
- for (int i = 0; 1; i ++) {
- char32 c = MelderReadText_getChar (me); // read past first '"'
- if (c == U'\0')
- Melder_throw (U"Early end of text detected while reading a string (line ", MelderReadText_getLineNumber (me), U").");
- if (c == U'\"') {
- char32 next = MelderReadText_getChar (me);
- if (next == U'\0') { break; } // closing quote is last character in file: OK
- if (next != U'\"') {
- if (Melder_isHorizontalOrVerticalSpace (next)) {
- // closing quote is followed by whitespace: it is OK to skip this whitespace (no need to "ungetChar")
- } else {
- char32 kar2 [2] = { next, U'\0' };
- Melder_throw (U"Character ", kar2, U" following quote (line ", MelderReadText_getLineNumber (me), U"). End of string or undoubled quote?");
- }
- break; // the expected closing double quote; not added to the buffer
- } // else: add only one of the two quotes to the buffer
- }
- MelderString_appendCharacter (& buffer, c);
- }
- return buffer. string;
- }
- #undef false
- #undef true
- #include "enums_getText.h"
- #include "abcio_enums.h"
- #include "enums_getValue.h"
- #include "abcio_enums.h"
- int texgeti8 (MelderReadText text) {
- try {
- int64 externalValue = getInteger (text);
- if (externalValue < INT8_MIN || externalValue > INT8_MAX)
- Melder_throw (U"Value (", externalValue, U") out of range (-128 .. +127).");
- return (int) externalValue;
- } catch (MelderError) {
- Melder_throw (U"Signed small integer not read from text file.");
- }
- }
- int16 texgeti16 (MelderReadText text) {
- try {
- int64 externalValue = getInteger (text);
- if (externalValue < INT16_MIN || externalValue > INT16_MAX)
- Melder_throw (U"Value (", externalValue, U") out of range (-32768 .. +32767).");
- return (int16) externalValue;
- } catch (MelderError) {
- Melder_throw (U"Signed short integer not read from text file.");
- }
- }
- int32 texgeti32 (MelderReadText text) {
- try {
- int64 externalValue = getInteger (text);
- if (externalValue < INT32_MIN || externalValue > INT32_MAX)
- Melder_throw (U"Value (", externalValue, U") out of range (-2147483648 .. +2147483647).");
- return (int32) externalValue;
- } catch (MelderError) {
- Melder_throw (U"Signed integer not read from text file.");
- }
- }
- integer texgetinteger (MelderReadText text) {
- try {
- int64 externalValue = getInteger (text);
- if (externalValue < INT32_MIN || externalValue > INT32_MAX)
- Melder_throw (U"Value (", externalValue, U") out of range (-2147483648 .. +2147483647)."); // this will change
- return (integer) externalValue;
- } catch (MelderError) {
- Melder_throw (U"Signed integer not read from text file.");
- }
- }
- unsigned int texgetu8 (MelderReadText text) {
- try {
- uint64 externalValue = getUnsigned (text);
- if (externalValue > UINT8_MAX)
- Melder_throw (U"Value (", externalValue, U") out of range (0 .. 255).");
- return (unsigned int) externalValue;
- } catch (MelderError) {
- Melder_throw (U"Unsigned small integer not read from text file.");
- }
- }
- uint16 texgetu16 (MelderReadText text) {
- try {
- uint64 externalValue = getUnsigned (text);
- if (externalValue > UINT16_MAX)
- Melder_throw (U"Value (", externalValue, U") out of range (0 .. 65535).");
- return (uint16) externalValue;
- } catch (MelderError) {
- Melder_throw (U"Unsigned short integer not read from text file.");
- }
- }
- uint32 texgetu32 (MelderReadText text) {
- try {
- uint64 externalValue = getUnsigned (text);
- if (externalValue > UINT32_MAX)
- Melder_throw (U"Value (", externalValue, U") out of range (0 .. 4294967295).");
- return (uint32) externalValue;
- } catch (MelderError) {
- Melder_throw (U"Unsigned integer not read from text file.");
- }
- }
- double texgetr32 (MelderReadText text) { return getReal (text); }
- double texgetr64 (MelderReadText text) { return getReal (text); }
- double texgetr80 (MelderReadText text) { return getReal (text); }
- dcomplex texgetc64 (MelderReadText text) { dcomplex z; z.re = getReal (text); z.im = getReal (text); return z; }
- dcomplex texgetc128 (MelderReadText text) { dcomplex z; z.re = getReal (text); z.im = getReal (text); return z; }
- int texgete8 (MelderReadText text, enum_generic_getValue getValue) { return getEnum (text, getValue); }
- int texgete16 (MelderReadText text, enum_generic_getValue getValue) { return getEnum (text, getValue); }
- bool texgeteb (MelderReadText text) { return getEnum (text, (enum_generic_getValue) kBoolean_getValue); }
- bool texgeteq (MelderReadText text) { return getEnum (text, (enum_generic_getValue) kQuestion_getValue); }
- bool texgetex (MelderReadText text) { return getEnum (text, (enum_generic_getValue) kExistence_getValue); }
- autostring8 texgets16 (MelderReadText text) { return Melder_32to8 (peekString (text)); }
- autostring8 texgets32 (MelderReadText text) { return Melder_32to8 (peekString (text)); }
- autostring32 texgetw16 (MelderReadText text) { return Melder_dup (peekString (text)); }
- autostring32 texgetw32 (MelderReadText text) { return Melder_dup (peekString (text)); }
- void texindent (MelderFile file) { file -> indent += 4; }
- void texexdent (MelderFile file) { file -> indent -= 4; }
- void texresetindent (MelderFile file) { file -> indent = 0; }
- void texputintro (MelderFile file, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- if (file -> verbose) {
- MelderFile_write (file, U"\n");
- for (int iindent = 1; iindent <= file -> indent; iindent ++) {
- MelderFile_write (file, U" ");
- }
- MelderFile_write (file,
- s1 && s1 [0] == U'd' && s1 [1] == U'_' ? & s1 [2] : & s1 [0],
- s2 && s2 [0] == U'd' && s2 [1] == U'_' ? & s2 [2] : & s2 [0],
- s3 && s3 [0] == U'd' && s3 [1] == U'_' ? & s3 [2] : & s3 [0],
- s4 && s4 [0] == U'd' && s4 [1] == U'_' ? & s4 [2] : & s4 [0],
- s5 && s5 [0] == U'd' && s5 [1] == U'_' ? & s5 [2] : & s5 [0],
- s6 && s6 [0] == U'd' && s6 [1] == U'_' ? & s6 [2] : & s6 [0]);
- }
- file -> indent += 4;
- }
- #define PUTLEADER \
- MelderFile_write (file, U"\n"); \
- if (file -> verbose) { \
- for (int iindent = 1; iindent <= file -> indent; iindent ++) { \
- MelderFile_write (file, U" "); \
- } \
- MelderFile_write (file, \
- s1 && s1 [0] == U'd' && s1 [1] == U'_' ? & s1 [2] : & s1 [0], \
- s2 && s2 [0] == U'd' && s2 [1] == U'_' ? & s2 [2] : & s2 [0], \
- s3 && s3 [0] == U'd' && s3 [1] == U'_' ? & s3 [2] : & s3 [0], \
- s4 && s4 [0] == U'd' && s4 [1] == U'_' ? & s4 [2] : & s4 [0], \
- s5 && s5 [0] == U'd' && s5 [1] == U'_' ? & s5 [2] : & s5 [0], \
- s6 && s6 [0] == U'd' && s6 [1] == U'_' ? & s6 [2] : & s6 [0]); \
- }
- void texputi8 (MelderFile file, int i, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = " : nullptr, i, file -> verbose ? U" " : nullptr);
- }
- void texputi16 (MelderFile file, int i, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = " : nullptr, i, file -> verbose ? U" " : nullptr);
- }
- void texputi32 (MelderFile file, long i, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = " : nullptr, i, file -> verbose ? U" " : nullptr);
- }
- void texputinteger (MelderFile file, integer number, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = " : nullptr, number, file -> verbose ? U" " : nullptr);
- }
- void texputu8 (MelderFile file, unsigned int u, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = " : nullptr, u, file -> verbose ? U" " : nullptr);
- }
- void texputu16 (MelderFile file, unsigned int u, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = " : nullptr, u, file -> verbose ? U" " : nullptr);
- }
- void texputu32 (MelderFile file, unsigned long u, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = " : nullptr, u, file -> verbose ? U" " : nullptr);
- }
- void texputr32 (MelderFile file, double x, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = " : nullptr, Melder_single (x), file -> verbose ? U" " : nullptr);
- }
- void texputr64 (MelderFile file, double x, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = " : nullptr, x, file -> verbose ? U" " : nullptr);
- }
- void texputc64 (MelderFile file, dcomplex z, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = " : nullptr, z, file -> verbose ? U" i " : nullptr);
- }
- void texputc128 (MelderFile file, dcomplex z, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = " : nullptr, z, file -> verbose ? U" i " : nullptr);
- }
- void texpute8 (MelderFile file, int i, conststring32 (*getText) (int), conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = <" : U"<", getText (i), file -> verbose ? U"> " : U">");
- }
- void texpute16 (MelderFile file, int i, conststring32 (*getText) (int), conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = <" : U"<", getText (i), file -> verbose ? U"> " : U">");
- }
- void texputeb (MelderFile file, bool i, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = " : nullptr, i ? U"<true>" : U"<false>", file -> verbose ? U" " : nullptr);
- }
- void texputeq (MelderFile file, bool i, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U"? " : nullptr, i ? U"<yes>" : U"<no>", file -> verbose ? U" " : nullptr);
- }
- void texputex (MelderFile file, bool i, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U"? " : nullptr, i ? U"<exists>" : U"<absent>", file -> verbose ? U" " : nullptr);
- }
- void texputs8 (MelderFile file, const char *s, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = \"" : U"\"");
- if (s) {
- char c;
- while ((c = *s ++) != '\0') {
- MelderFile_writeCharacter (file, (char32) (char8) c);
- if (c == U'\"') MelderFile_writeCharacter (file, (char32) (char8) c); // double any internal quotes
- }
- }
- MelderFile_write (file, file -> verbose ? U"\" " : U"\"");
- }
- void texputs16 (MelderFile file, const char *s, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = \"" : U"\"");
- if (s) {
- char c;
- while ((c = *s ++) != '\0') {
- MelderFile_writeCharacter (file, (char32) (char8) c);
- if (c == '\"') MelderFile_writeCharacter (file, (char32) (char8) c); // double any internal quotes
- }
- }
- MelderFile_write (file, file -> verbose ? U"\" " : U"\"");
- }
- void texputs32 (MelderFile file, const char *s, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = \"" : U"\"");
- if (s) {
- char c;
- while ((c = *s ++) != '\0') {
- MelderFile_writeCharacter (file, (char32) (char8) c);
- if (c == '\"') MelderFile_writeCharacter (file, (char32) (char8) c); // double any internal quotes
- }
- }
- MelderFile_write (file, file -> verbose ? U"\" " : U"\"");
- }
- void texputw16 (MelderFile file, conststring32 s, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = \"" : U"\"");
- if (s) {
- char32 c;
- while ((c = *s ++) != U'\0') {
- MelderFile_writeCharacter (file, c);
- if (c == U'\"') MelderFile_writeCharacter (file, c); // double any internal quotes
- }
- }
- MelderFile_write (file, file -> verbose ? U"\" " : U"\"");
- }
- void texputw32 (MelderFile file, conststring32 s, conststring32 s1, conststring32 s2, conststring32 s3, conststring32 s4, conststring32 s5, conststring32 s6) {
- PUTLEADER
- MelderFile_write (file, file -> verbose ? U" = \"" : U"\"");
- if (s) {
- char32 c;
- while ((c = *s ++) != U'\0') {
- MelderFile_writeCharacter (file, c);
- if (c == U'\"') MelderFile_writeCharacter (file, c); // double any internal quotes
- }
- }
- MelderFile_write (file, file -> verbose ? U"\" " : U"\"");
- }
- /********** machine-independent binary I/O **********/
- /* Optimizations for machines for which some of the formats are native. */
- /* On which machines is "short" a two's complement Big-Endian (MSB-first) 2-byte word? */
- #if defined (macintosh) && TARGET_RT_BIG_ENDIAN == 1
- #define binario_16bitBE 1
- #define binario_16bitLE 0
- #elif defined (_WIN32) || defined (macintosh) && TARGET_RT_LITTLE_ENDIAN == 1
- #define binario_16bitBE 0
- #define binario_16bitLE 1
- #else
- #define binario_16bitBE 0
- #define binario_16bitLE 0
- #endif
- /* On which machines is "long" a two's complement Big-Endian (MSB-first) 4-byte word? */
- #if defined (macintosh) && TARGET_RT_BIG_ENDIAN == 1
- #define binario_32bitBE 1
- #define binario_32bitLE 0
- #elif defined (_WIN32) || defined (macintosh) && TARGET_RT_LITTLE_ENDIAN == 1
- #define binario_32bitBE 0
- #define binario_32bitLE 1
- #else
- #define binario_32bitBE 0
- #define binario_32bitLE 0
- #endif
- /* On which machines is "float" IEEE, four bytes, Most Significant Bit first? */
- #if defined (macintosh) && TARGET_RT_BIG_ENDIAN == 1
- #define binario_floatIEEE4msb (sizeof (float) == 4)
- #define binario_floatIEEE4lsb 0
- #elif defined (_WIN32) || defined (macintosh) && TARGET_RT_LITTLE_ENDIAN == 1
- #define binario_floatIEEE4msb 0
- #define binario_floatIEEE4lsb (sizeof (float) == 4)
- #else
- #define binario_floatIEEE4msb 0
- #define binario_floatIEEE4lsb 0
- #endif
- /* On which machines is "double" IEEE, eight bytes, Most Significant Bit first? */
- #if defined (macintosh) && TARGET_RT_BIG_ENDIAN == 1
- #define binario_doubleIEEE8msb (sizeof (double) == 8)
- #define binario_doubleIEEE8lsb 0
- #elif defined (_WIN32) || defined (macintosh) && TARGET_RT_LITTLE_ENDIAN == 1
- #define binario_doubleIEEE8msb 0
- #define binario_doubleIEEE8lsb (sizeof (double) == 8)
- #else
- #define binario_doubleIEEE8msb 0
- #define binario_doubleIEEE8lsb 0
- #endif
- /*
- The routines bingetr32, bingetr64, binputr32, and binputr64,
- were implemented by Paul Boersma from the descriptions of the IEEE floating-point formats,
- as found in the MC68881/MC68882 User's Manual by Motorola (second edition, 1989).
- The following copyright notice only refers to the code of bingetr10 and binputr10.
- */
- /* Copyright (C) 1988-1991 Apple Computer, Inc.
- * All rights reserved.
- *
- * Warranty Information
- * Even though Apple has reviewed this software, Apple makes no warranty
- * or representation, either express or implied, with respect to this
- * software, its quality, accuracy, merchantability, or fitness for a
- * particular purpose. As a result, this software is provided "as is,"
- * and you, its user, are assuming the entire risk as to its quality
- * and accuracy.
- *
- * This code may be used and freely distributed as long as it includes
- * this copyright notice and the above warranty information.
- *
- * Machine-independent I/O routines for IEEE floating-point numbers.
- *
- * NaN's and infinities are converted to HUGE_VAL or HUGE, which
- * happens to be infinity on IEEE machines. Unfortunately, it is
- * impossible to preserve NaN's in a machine-independent way.
- * Infinities are, however, preserved on IEEE machines.
- *
- * These routines have been tested on the following machines:
- * Apple Macintosh, MPW 3.1 C compiler
- * Apple Macintosh, THINK C compiler
- * Silicon Graphics IRIS, MIPS compiler
- * Cray X/MP and Y/MP
- * Digital Equipment VAX
- *
- * Implemented by Malcolm Slaney and Ken Turkowski.
- *
- * Malcolm Slaney contributions during 1988-1990 include big- and little-
- * endian file I/O, conversion to and from Motorola's extended 80-bit
- * floating-point format, and conversions to and from IEEE single-
- * precision floating-point format.
- *
- * In 1991, Ken Turkowski implemented the conversions to and from
- * IEEE double-precision format, added more precision to the extended
- * conversions, and accommodated conversions involving +/- infinity,
- * NaN's, and denormalized numbers.
- */
- // QUESTION: do the following work correctly if a long is 64 bits?
- # define FloatToUnsigned(f) \
- ((unsigned long)(((long)((f) - 2147483648.0)) + 2147483647L + 1))
- # define UnsignedToFloat(u) \
- (((double)((long)((u) - 2147483647L - 1))) + 2147483648.0)
- //#define FloatToUnsigned(f) (uint32) (f)
- //#define UnsignedToFloat(u) (double) (u)
- /****************************************************************
- * Extended precision IEEE floating-point conversion routines.
- ****************************************************************/
- /*
- * C O N V E R T T O I E E E E X T E N D E D
- */
- /*
- * C O N V E R T F R O M I E E E E X T E N D E D
- */
- /*************** End of Apple Computer intermezzo. ***************/
- static void readError (FILE *f, conststring32 text) {
- Melder_throw (feof (f) ? U"Reached end of file" : U"Error in file", U" while trying to read ", text);
- }
- static void writeError (conststring32 text) {
- Melder_throw (U"Error in file while trying to write ", text);
- }
- unsigned int bingetu8 (FILE *f) {
- try {
- int externalValue = getc (f); // either -1 (EOF) or in the range 0..255
- if (externalValue < 0) readError (f, U"a byte.");
- return (unsigned int) externalValue;
- } catch (MelderError) {
- Melder_throw (U"Unsigned integer not read from 1 byte in binary file.");
- }
- }
- void binputu8 (unsigned int u, FILE *f) {
- try {
- if (putc ((int) u, f) < 0) writeError (U"a byte.");
- } catch (MelderError) {
- Melder_throw (U"Unsigned integer not written to 1 byte in binary file.");
- }
- }
- int bingeti8 (FILE *f) {
- try {
- int externalValue = getc (f);
- if (externalValue < 0) readError (f, U"a byte.");
- return (signed char) externalValue; // this converts e.g. 200 to -56
- } catch (MelderError) {
- Melder_throw (U"Signed integer not read from 1 byte in binary file.");
- }
- }
- void binputi8 (int u, FILE *f) {
- try {
- if (putc (u, f) < 0) writeError (U"a byte.");
- } catch (MelderError) {
- Melder_throw (U"Signed integer not written to 1 byte in binary file.");
- }
- }
- bool bingetbool8 (FILE *f) {
- try {
- int externalValue = getc (f);
- if (externalValue < 0) readError (f, U"a byte.");
- return (bool) externalValue; // this converts e.g. 200 to true
- } catch (MelderError) {
- Melder_throw (U"Boolean not read from 1 byte in binary file.");
- }
- }
- void binputbool8 (bool value, FILE *f) {
- try {
- if (putc (value, f) < 0) writeError (U"a byte.");
- } catch (MelderError) {
- Melder_throw (U"Boolean not written to 1 byte in binary file.");
- }
- }
- int bingete8 (FILE *f, int min, int max, conststring32 type) {
- try {
- int externalValue = getc (f);
- if (externalValue < 0) readError (f, U"a byte.");
- int result = (signed char) externalValue; // this converts e.g. 200 to -56, so the enumerated type is signed
- if (result < min || result > max)
- Melder_throw (result, U" is not a value of enumerated type <", type, U">.");
- return result;
- } catch (MelderError) {
- Melder_throw (U"Enumerated type not read from 1 byte in binary file.");
- }
- }
- void binpute8 (int value, FILE *f) {
- try {
- if (putc (value, f) < 0) writeError (U"a byte.");
- } catch (MelderError) {
- Melder_throw (U"Enumerated type not written to 1 byte in binary file.");
- }
- }
- static int bitsInReadBuffer = 0;
- static unsigned char readBuffer;
- #define macro_bingetb(nbits) \
- unsigned int bingetb##nbits (FILE *f) { \
- if (bitsInReadBuffer < nbits) { \
- int externalValue = fgetc (f); \
- if (externalValue < 0) readError (f, U"a bit."); \
- readBuffer = (unsigned char) externalValue; \
- bitsInReadBuffer = 8; \
- } \
- unsigned char result = (unsigned char) ((uint32) readBuffer << (8 - bitsInReadBuffer)); \
- bitsInReadBuffer -= nbits; \
- return result >> (8 - nbits); \
- }
- macro_bingetb (1)
- macro_bingetb (2)
- macro_bingetb (3)
- macro_bingetb (4)
- macro_bingetb (5)
- macro_bingetb (6)
- macro_bingetb (7)
- void bingetb (FILE *f) { (void) f; bitsInReadBuffer = 0; }
- int16 bingeti16 (FILE *f) {
- try {
- if (binario_16bitBE && Melder_debug != 18) {
- int16 s;
- if (fread (& s, sizeof (int16), 1, f) != 1) readError (f, U"a signed 16-bit integer.");
- return s;
- } else {
- uint8 bytes [2];
- if (fread (bytes, sizeof (uint8), 2, f) != 2) readError (f, U"two bytes.");
- return (int16) // reinterpret sign bit
- ((uint16) ((uint16) bytes [0] << 8) |
- (uint16) bytes [1]);
- }
- } catch (MelderError) {
- Melder_throw (U"Signed integer not read from 2 bytes in binary file.");
- }
- }
- int16 bingeti16LE (FILE *f) {
- try {
- if (binario_16bitLE && Melder_debug != 18) {
- int16 s;
- if (fread (& s, sizeof (int16), 1, f) != 1) readError (f, U"a signed 16-bit integer.");
- return s;
- } else {
- uint8 bytes [2];
- if (fread (bytes, sizeof (uint8), 2, f) != 2) readError (f, U"two bytes.");
- return (int16) // reinterpret sign bit
- ((uint16) ((uint16) bytes [1] << 8) |
- (uint16) bytes [0]);
- }
- } catch (MelderError) {
- Melder_throw (U"Signed integer not read from 2 bytes in binary file.");
- }
- }
- integer bingetinteger16BE (FILE *f) {
- try {
- if (binario_16bitBE && Melder_debug != 18) {
- int16 s;
- if (fread (& s, sizeof (int16), 1, f) != 1) readError (f, U"a signed 16-bit integer.");
- return s;
- } else {
- uint8 bytes [2];
- if (fread (bytes, sizeof (uint8), 2, f) != 2) readError (f, U"two bytes.");
- return (int16) // reinterpret sign bit
- ((uint16) ((uint16) bytes [0] << 8) |
- (uint16) bytes [1]);
- }
- } catch (MelderError) {
- Melder_throw (U"Signed integer not read from 2 bytes in binary file.");
- }
- }
- uint16 bingetu16 (FILE *f) {
- try {
- if (binario_16bitBE && Melder_debug != 18) {
- uint16 s;
- if (fread (& s, sizeof (uint16), 1, f) != 1) readError (f, U"an unsigned 16-bit integer.");
- return s; // without sign extension
- } else {
- uint8 bytes [2];
- if (fread (bytes, sizeof (uint8), 2, f) != 2) readError (f, U"two bytes.");
- return
- (uint16) ((uint16) bytes [0] << 8) |
- (uint16) bytes [1];
- }
- } catch (MelderError) {
- Melder_throw (U"Unsigned integer not read from 2 bytes in binary file.");
- }
- }
- uint16 bingetu16LE (FILE *f) {
- try {
- if (binario_16bitLE && Melder_debug != 18) {
- uint16 s;
- if (fread (& s, sizeof (uint16), 1, f) != 1) readError (f, U"an unsigned 16-bit integer.");
- return s; // without sign extension
- } else {
- uint8 bytes [2];
- if (fread (bytes, sizeof (uint8), 2, f) != 2) readError (f, U"two bytes.");
- return
- (uint16) ((uint16) bytes [1] << 8) |
- (uint16) bytes [0];
- }
- } catch (MelderError) {
- Melder_throw (U"Unsigned integer not read from 2 bytes in binary file.");
- }
- }
- int bingete16 (FILE *f, int min, int max, conststring32 type) {
- try {
- int16 result;
- if (binario_16bitBE && Melder_debug != 18) {
- if (fread (& result, sizeof (int16), 1, f) != 1) readError (f, U"a signed 16-bit integer.");
- } else {
- uint8 bytes [2];
- if (fread (bytes, sizeof (uint8), 2, f) != 2) readError (f, U"two bytes.");
- uint16 externalValue =
- (uint16) ((uint16) bytes [0] << 8) |
- (uint16) bytes [1];
- result = (int16) externalValue;
- }
- if (result < min || result > max)
- Melder_throw (result, U" is not a value of enumerated type \"", type, U"\".");
- return (int) result;
- } catch (MelderError) {
- Melder_throw (U"Enumerated value not read from 2 bytes in binary file.");
- }
- }
- int32 bingeti24 (FILE *f) {
- try {
- uint8 bytes [3];
- if (fread (bytes, sizeof (uint8), 3, f) != 3) readError (f, U"three bytes.");
- uint32 externalValue =
- (uint32) ((uint32) bytes [0] << 16) |
- (uint32) ((uint32) bytes [1] << 8) |
- (uint32) bytes [2];
- if ((bytes [0] & 128) != 0) // is the 24-bit sign bit on?
- externalValue |= 0xFF00'0000; // extend negative sign to 32 bits
- return (int32) externalValue; // reinterpret sign bit
- } catch (MelderError) {
- Melder_throw (U"Signed integer not read from 3 bytes in binary file.");
- }
- }
- int32 bingeti24LE (FILE *f) {
- try {
- uint8 bytes [3];
- if (fread (bytes, sizeof (uint8), 3, f) != 3) readError (f, U"three bytes.");
- uint32 externalValue =
- (uint32) ((uint32) bytes [2] << 16) |
- (uint32) ((uint32) bytes [1] << 8) |
- (uint32) bytes [0];
- if ((bytes [2] & 128) != 0) // is the 24-bit sign bit on?
- externalValue |= 0xFF00'0000; // extend negative sign to 32 bits
- return (int32) externalValue; // reinterpret sign bit
- } catch (MelderError) {
- Melder_throw (U"Signed integer not read from 3 bytes in binary file.");
- }
- }
- int32 bingeti32 (FILE *f) {
- try {
- if (binario_32bitBE && Melder_debug != 18) {
- int32 l;
- if (fread (& l, sizeof (int32), 1, f) != 1) readError (f, U"a signed 32-bit integer.");
- return l;
- } else {
- uint8 bytes [4];
- if (fread (bytes, sizeof (uint8), 4, f) != 4) readError (f, U"four bytes.");
- return (int32)
- ((uint32) ((uint32) bytes [0] << 24) |
- (uint32) ((uint32) bytes [1] << 16) |
- (uint32) ((uint32) bytes [2] << 8) |
- (uint32) bytes [3]);
- }
- } catch (MelderError) {
- Melder_throw (U"Signed integer not read from 4 bytes in binary file.");
- }
- }
- int32 bingeti32LE (FILE *f) {
- try {
- if (binario_32bitLE && Melder_debug != 18) {
- int32 l;
- if (fread (& l, sizeof (int32), 1, f) != 1) readError (f, U"a signed 32-bit integer.");
- return l;
- } else {
- uint8 bytes [4];
- if (fread (bytes, sizeof (uint8), 4, f) != 4) readError (f, U"four bytes.");
- return (int32) // reinterpret sign bit
- ((uint32) ((uint32) bytes [3] << 24) |
- (uint32) ((uint32) bytes [2] << 16) |
- (uint32) ((uint32) bytes [1] << 8) |
- (uint32) bytes [0]);
- }
- } catch (MelderError) {
- Melder_throw (U"Signed integer not read from 4 bytes in binary file.");
- }
- }
- integer bingetinteger32BE (FILE *f) {
- try {
- if (binario_32bitBE && Melder_debug != 18) {
- int32 l;
- if (fread (& l, sizeof (int32), 1, f) != 1) readError (f, U"a signed 32-bit integer.");
- return (integer) l;
- } else {
- uint8 bytes [4];
- if (fread (bytes, sizeof (uint8), 4, f) != 4) readError (f, U"four bytes.");
- return (integer) (int32)
- ((uint32) ((uint32) bytes [0] << 24) |
- (uint32) ((uint32) bytes [1] << 16) |
- (uint32) ((uint32) bytes [2] << 8) |
- (uint32) bytes [3]);
- }
- } catch (MelderError) {
- Melder_throw (U"Signed integer not read from 4 bytes in binary file.");
- }
- }
- uint32 bingetu32 (FILE *f) {
- try {
- if (binario_32bitBE && Melder_debug != 18) {
- uint32 l;
- if (fread (& l, sizeof (uint32), 1, f) != 1) readError (f, U"an unsigned 32-bit integer.");
- return l;
- } else {
- uint8 bytes [4];
- if (fread (bytes, sizeof (uint8), 4, f) != 4) readError (f, U"four bytes.");
- return
- (uint32) ((uint32) bytes [0] << 24) |
- (uint32) ((uint32) bytes [1] << 16) |
- (uint32) ((uint32) bytes [2] << 8) |
- (uint32) bytes [3];
- }
- } catch (MelderError) {
- Melder_throw (U"Unsigned integer not read from 4 bytes in binary file.");
- }
- }
- uint32 bingetu32LE (FILE *f) {
- try {
- if (binario_32bitLE && Melder_debug != 18) {
- uint32 l;
- if (fread (& l, sizeof (uint32), 1, f) != 1) readError (f, U"an unsigned 32-bit integer.");
- return l;
- } else {
- uint8 bytes [4];
- if (fread (bytes, sizeof (uint8), 4, f) != 4) readError (f, U"four bytes.");
- return
- (uint32) ((uint32) bytes [3] << 24) |
- (uint32) ((uint32) bytes [2] << 16) |
- (uint32) ((uint32) bytes [1] << 8) |
- (uint32) bytes [0];
- }
- } catch (MelderError) {
- Melder_throw (U"Unsigned integer not read from 4 bytes in binary file.");
- }
- }
- double bingetr32 (FILE *f) {
- try {
- if (binario_floatIEEE4msb && Melder_debug != 18) {
- float x;
- if (fread (& x, sizeof (float), 1, f) != 1) readError (f, U"a 32-bit floating-point number.");
- return x;
- } else {
- uint8 bytes [4];
- if (fread (bytes, sizeof (uint8), 4, f) != 4) readError (f, U"four bytes.");
- int32 exponent = (int32)
- ((uint32) ((uint32) ((uint32) bytes [0] & 0x0000'007F) << 1) |
- (uint32) ((uint32) ((uint32) bytes [1] & 0x0000'0080) >> 7)); // between 0 and 255 (it's signed because we're going to subtract something)
- uint32 mantissa =
- (uint32) ((uint32) ((uint32) bytes [1] & 0x0000'007F) << 16) |
- (uint32) ((uint32) bytes [2] << 8) |
- (uint32) bytes [3];
- double x;
- if (exponent == 0)
- if (mantissa == 0) x = 0.0;
- else x = ldexp ((double) mantissa, exponent - 149); // denormalized
- else if (exponent == 0x0000'00FF) // Infinity or Not-a-Number
- return undefined;
- else // finite
- x = ldexp ((double) (mantissa | 0x0080'0000), exponent - 150);
- return bytes [0] & 0x80 ? - x : x;
- }
- } catch (MelderError) {
- Melder_throw (U"Floating-point number not read from 4 bytes in binary file.");
- }
- }
- double bingetr32LE (FILE *f) {
- try {
- if (binario_floatIEEE4lsb && Melder_debug != 18) {
- float x;
- if (fread (& x, sizeof (float), 1, f) != 1) readError (f, U"a 32-bit floating-point number.");
- return x;
- } else {
- uint8 bytes [4];
- if (fread (bytes, sizeof (uint8), 4, f) != 4) readError (f, U"four bytes.");
- int32 exponent = (int32)
- ((uint32) ((uint32) ((uint32) bytes [3] & 0x0000'007F) << 1) |
- (uint32) ((uint32) ((uint32) bytes [2] & 0x0000'0080) >> 7));
- uint32 mantissa =
- (uint32) ((uint32) ((uint32) bytes [2] & 0x0000'007F) << 16) |
- (uint32) ((uint32) bytes [1] << 8) |
- (uint32) bytes [0];
- double x;
- if (exponent == 0)
- if (mantissa == 0) x = 0.0;
- else x = ldexp ((double) mantissa, exponent - 149); // denormalized
- else if (exponent == 0x0000'00FF) // Infinity or Not-a-Number
- return undefined;
- else // finite
- x = ldexp ((double) (mantissa | 0x0080'0000), exponent - 150);
- return bytes [3] & 0x80 ? - x : x;
- }
- } catch (MelderError) {
- Melder_throw (U"Floating-point number not read from 4 bytes in binary file.");
- }
- }
- double bingetr64 (FILE *f) {
- try {
- if (binario_doubleIEEE8msb && Melder_debug != 18 || Melder_debug == 181) {
- double x;
- if (fread (& x, sizeof (double), 1, f) != 1) readError (f, U"a 64-bit floating-point number.");
- return x;
- } else {
- uint8 bytes [8];
- if (fread (bytes, sizeof (uint8), 8, f) != 8) readError (f, U"eight bytes.");
- int32 exponent = (int32)
- ((uint32) ((uint32) ((uint32) bytes [0] & 0x0000'007F) << 4) |
- (uint32) ((uint32) ((uint32) bytes [1] & 0x0000'00F0) >> 4));
- uint32 highMantissa =
- (uint32) ((uint32) ((uint32) bytes [1] & 0x0000'000F) << 16) |
- (uint32) ((uint32) bytes [2] << 8) |
- (uint32) bytes [3];
- uint32 lowMantissa =
- (uint32) ((uint32) bytes [4] << 24) |
- (uint32) ((uint32) bytes [5] << 16) |
- (uint32) ((uint32) bytes [6] << 8) |
- (uint32) bytes [7];
- double x;
- if (exponent == 0)
- if (highMantissa == 0 && lowMantissa == 0) x = 0.0;
- else x = ldexp ((double) highMantissa, exponent - 1042) +
- ldexp ((double) lowMantissa, exponent - 1074); // denormalized
- else if (exponent == 0x0000'07FF) // Infinity or Not-a-Number
- return undefined;
- else
- x = ldexp ((double) (highMantissa | 0x0010'0000), exponent - 1043) +
- ldexp ((double) lowMantissa, exponent - 1075);
- return bytes [0] & 0x80 ? - x : x;
- }
- } catch (MelderError) {
- Melder_throw (U"Floating-point number not read from 8 bytes in binary file.");
- }
- }
- double bingetr80 (FILE *f) {
- try {
- uint8 bytes [10];
- if (fread (bytes, sizeof (uint8), 10, f) != 10) readError (f, U"ten bytes.");
- int32 exponent = (int32)
- ((uint32) ((uint32) ((uint32) bytes [0] & 0x0000'007F) << 8) |
- (uint32) bytes [1]); // between 0 and 32767
- uint32 highMantissa =
- (uint32) ((uint32) bytes [2] << 24) |
- (uint32) ((uint32) bytes [3] << 16) |
- (uint32) ((uint32) bytes [4] << 8) |
- (uint32) bytes [5];
- uint32 lowMantissa =
- (uint32) ((uint32) bytes [6] << 24) |
- (uint32) ((uint32) bytes [7] << 16) |
- (uint32) ((uint32) bytes [8] << 8) |
- (uint32) bytes [9];
- double x;
- if (exponent == 0 && highMantissa == 0 && lowMantissa == 0) x = 0.0;
- else if (exponent == 0x0000'7FFF) return undefined; // Infinity or NaN
- else {
- exponent -= 16'383; // between -16'382 and +16'383
- x = ldexp ((double) highMantissa, exponent - 31);
- x += ldexp ((double) lowMantissa, exponent - 63);
- }
- return bytes [0] & 0x80 ? - x : x;
- } catch (MelderError) {
- Melder_throw (U"Floating-point number not read from 10 bytes in binary file.");
- }
- }
- static int bitsInWriteBuffer = 0;
- static unsigned char writeBuffer = 0;
- #define macro_binputb(nbits) \
- void binputb##nbits (unsigned int value, FILE *f) { \
- if (bitsInWriteBuffer + nbits > 8) { \
- if (fputc (writeBuffer, f) < 0) writeError (U"a bit."); \
- bitsInWriteBuffer = 0; \
- writeBuffer = 0; \
- } \
- writeBuffer |= (value << (8 - nbits)) >> bitsInWriteBuffer; \
- bitsInWriteBuffer += nbits; \
- }
- macro_binputb (1)
- macro_binputb (2)
- macro_binputb (3)
- macro_binputb (4)
- macro_binputb (5)
- macro_binputb (6)
- macro_binputb (7)
- void binputb (FILE *f) {
- if (bitsInWriteBuffer == 0) return;
- if (fputc (writeBuffer, f) < 0) writeError (U"a bit."); // flush
- bitsInWriteBuffer = 0;
- writeBuffer = 0;
- }
- void binputi16 (int16 i, FILE *f) {
- try {
- if (binario_16bitBE && Melder_debug != 18) {
- if (fwrite (& i, sizeof (short), 1, f) != 1) writeError (U"a signed 16-bit integer.");
- } else {
- uint8 bytes [2];
- bytes [0] = (uint8) (i >> 8); // truncate
- bytes [1] = (uint8) i; // truncate
- if (fwrite (bytes, sizeof (uint8), 2, f) != 2) writeError (U"two bytes.");
- }
- } catch (MelderError) {
- Melder_throw (U"Signed integer not written to 2 bytes in binary file.");
- }
- }
- void binputi16LE (int16 i, FILE *f) {
- try {
- if (binario_16bitLE && Melder_debug != 18) {
- if (fwrite (& i, sizeof (short), 1, f) != 1) writeError (U"a signed 16-bit integer.");
- } else {
- uint8 bytes [2];
- bytes [1] = (uint8) (i >> 8); // truncate
- bytes [0] = (uint8) i; // truncate
- if (fwrite (bytes, sizeof (uint8), 2, f) != 2) writeError (U"two bytes.");
- }
- } catch (MelderError) {
- Melder_throw (U"Signed integer not written to 2 bytes in binary file.");
- }
- }
- void binputinteger16BE (integer i, FILE *f) {
- try {
- if (i < INT16_MIN || i > INT16_MAX)
- Melder_throw (U"The number ", i, U" is too big to fit into 16 bits."); // this will change in the future
- uint8 bytes [2];
- bytes [0] = (uint8) (i >> 8); // truncate
- bytes [1] = (uint8) i; // truncate
- if (fwrite (bytes, sizeof (uint8), 2, f) != 2) writeError (U"two bytes.");
- } catch (MelderError) {
- Melder_throw (U"Signed integer not written to 2 bytes in binary file.");
- }
- }
- void binputu16 (uint16 u, FILE *f) {
- try {
- if (binario_16bitBE && Melder_debug != 18) {
- if (fwrite (& u, sizeof (uint16), 1, f) != 1) writeError (U"an unsigned 16-bit integer.");
- } else {
- uint8 bytes [2];
- bytes [0] = (uint8) (u >> 8); // truncate
- bytes [1] = (uint8) u; // truncate
- if (fwrite (bytes, sizeof (uint8), 2, f) != 2) writeError (U"two bytes.");
- }
- } catch (MelderError) {
- Melder_throw (U"Unsigned integer not written to 2 bytes in binary file.");
- }
- }
- void binputu16LE (uint16 u, FILE *f) {
- try {
- if (binario_16bitLE && Melder_debug != 18) {
- if (fwrite (& u, sizeof (uint16), 1, f) != 1) writeError (U"an unsigned 16-bit integer.");
- } else {
- uint8 bytes [2];
- bytes [1] = (uint8) (u >> 8); // truncate
- bytes [0] = (uint8) u; // truncate
- if (fwrite (bytes, sizeof (uint8), 2, f) != 2) writeError (U"two bytes.");
- }
- } catch (MelderError) {
- Melder_throw (U"Unsigned integer not written to 2 bytes in binary file.");
- }
- }
- void binpute16 (int value, FILE *f) {
- try {
- if (binario_16bitBE && Melder_debug != 18) {
- short s = value;
- if (fwrite (& s, sizeof (short), 1, f) != 1) writeError (U"a signed 16-bit integer");
- } else {
- uint8 bytes [2];
- bytes [0] = (uint8) (value >> 8); // truncate
- bytes [1] = (uint8) value; // truncate
- if (fwrite (bytes, sizeof (uint8), 2, f) != 2) writeError (U"two bytes.");
- }
- } catch (MelderError) {
- Melder_throw (U"Enumerated value not written to 2 bytes in binary file.");
- }
- }
- void binputi24 (int32 i, FILE *f) {
- try {
- uint8 bytes [3];
- bytes [0] = (uint8) (i >> 16); // truncate
- bytes [1] = (uint8) (i >> 8); // truncate
- bytes [2] = (uint8) i; // truncate
- if (fwrite (bytes, sizeof (uint8), 3, f) != 3) writeError (U"three bytes");
- } catch (MelderError) {
- Melder_throw (U"Signed integer not written to 3 bytes in binary file.");
- }
- }
- void binputi24LE (int32 i, FILE *f) {
- try {
- uint8 bytes [3];
- bytes [2] = (uint8) (i >> 16); // truncate
- bytes [1] = (uint8) (i >> 8); // truncate
- bytes [0] = (uint8) i; // truncate
- if (fwrite (bytes, sizeof (uint8), 3, f) != 3) writeError (U"three bytes");
- } catch (MelderError) {
- Melder_throw (U"Signed integer not written to 3 bytes in binary file.");
- }
- }
- void binputi32 (int32 i, FILE *f) {
- try {
- if (binario_32bitBE && Melder_debug != 18) {
- if (fwrite (& i, sizeof (int32), 1, f) != 1) writeError (U"a signed 32-bit integer.");
- } else {
- uint8 bytes [4];
- bytes [0] = (uint8) (i >> 24); // truncate
- bytes [1] = (uint8) (i >> 16); // truncate
- bytes [2] = (uint8) (i >> 8); // truncate
- bytes [3] = (uint8) i; // truncate
- if (fwrite (bytes, sizeof (uint8), 4, f) != 4) writeError (U"four bytes.");
- }
- } catch (MelderError) {
- Melder_throw (U"Signed integer not written to 4 bytes in binary file.");
- }
- }
- void binputi32LE (int32 i, FILE *f) {
- try {
- if (binario_32bitLE && Melder_debug != 18) {
- if (fwrite (& i, sizeof (int32), 1, f) != 1) writeError (U"a signed 32-bit integer.");
- } else {
- uint8 bytes [4];
- bytes [3] = (uint8) (i >> 24); // truncate
- bytes [2] = (uint8) (i >> 16); // truncate
- bytes [1] = (uint8) (i >> 8); // truncate
- bytes [0] = (uint8) i; // truncate
- if (fwrite (bytes, sizeof (uint8), 4, f) != 4) writeError (U"four bytes.");
- }
- } catch (MelderError) {
- Melder_throw (U"Signed integer not written to 4 bytes in binary file.");
- }
- }
- void binputinteger32BE (integer i, FILE *f) {
- try {
- if (i < INT32_MIN || i > INT32_MAX)
- Melder_throw (U"The number ", i, U" is too big to fit into 32 bits."); // this will change in the future
- uint8 bytes [4];
- bytes [0] = (uint8) (i >> 24); // truncate
- bytes [1] = (uint8) (i >> 16); // truncate
- bytes [2] = (uint8) (i >> 8); // truncate
- bytes [3] = (uint8) i; // truncate
- if (fwrite (bytes, sizeof (uint8), 4, f) != 4) writeError (U"a signed 32-bit integer.");
- } catch (MelderError) {
- Melder_throw (U"Signed integer not written to 4 bytes in binary file.");
- }
- }
- void binputu32 (uint32 u, FILE *f) {
- try {
- if (binario_32bitBE && Melder_debug != 18) {
- if (fwrite (& u, sizeof (uint32), 1, f) != 1) writeError (U"an unsigned 32-bit integer.");
- } else {
- uint8 bytes [4];
- bytes [0] = (uint8) (u >> 24); // truncate
- bytes [1] = (uint8) (u >> 16); // truncate
- bytes [2] = (uint8) (u >> 8); // truncate
- bytes [3] = (uint8) u; // truncate
- if (fwrite (bytes, sizeof (uint8), 4, f) != 4) writeError (U"four bytes.");
- }
- } catch (MelderError) {
- Melder_throw (U"Unsigned integer not written to 4 bytes in binary file.");
- }
- }
- void binputu32LE (uint32 u, FILE *f) {
- try {
- if (binario_32bitLE && Melder_debug != 18) {
- if (fwrite (& u, sizeof (uint32), 1, f) != 1) writeError (U"an unsigned 32-bit integer.");
- } else {
- uint8 bytes [4];
- bytes [3] = (uint8) (u >> 24); // truncate
- bytes [2] = (uint8) (u >> 16); // truncate
- bytes [1] = (uint8) (u >> 8); // truncate
- bytes [0] = (uint8) u; // truncate
- if (fwrite (bytes, sizeof (uint8), 4, f) != 4) writeError (U"four bytes.");
- }
- } catch (MelderError) {
- Melder_throw (U"Unsigned integer not written to 4 bytes in binary file.");
- }
- }
- void binputr32 (double x, FILE *f) {
- try {
- if (binario_floatIEEE4msb && Melder_debug != 18) {
- float x32 = (float) x; // convert down, with loss of precision
- if (fwrite (& x32, sizeof (float), 1, f) != 1) writeError (U"a 32-bit floating-point number.");
- } else {
- uint8 bytes [4];
- int sign, exponent;
- double fMantissa, fsMantissa;
- uint32 mantissa;
- if (x < 0.0) { sign = 0x0100; x *= -1.0; }
- else sign = 0;
- if (x == 0.0) { exponent = 0; mantissa = 0; }
- else {
- fMantissa = frexp (x, & exponent);
- if ((exponent > 128) || ! (fMantissa < 1.0)) // Infinity or Not-a-Number
- { exponent = sign | 0x00FF; mantissa = 0; } // Infinity
- else { // finite
- exponent += 126; // add bias
- if (exponent <= 0) { // denormalized
- fMantissa = ldexp (fMantissa, exponent - 1);
- exponent = 0;
- }
- exponent |= sign;
- fMantissa = ldexp (fMantissa, 24);
- fsMantissa = floor (fMantissa);
- mantissa = (uint32) fsMantissa & 0x007FFFFF;
- }
- }
- bytes [0] = (uint8) (exponent >> 1); // truncate: bits 2 through 9 (bit 9 is the sign bit)
- bytes [1] = (uint8) ((exponent << 7) | (mantissa >> 16)); // truncate
- bytes [2] = (uint8) (mantissa >> 8); // truncate
- bytes [3] = (uint8) mantissa; // truncate
- if (fwrite (bytes, sizeof (uint8), 4, f) != 4) writeError (U"four bytes.");
- }
- } catch (MelderError) {
- Melder_throw (U"Floating-point number not written to 4 bytes in binary file.");
- }
- }
- void binputr32LE (double x, FILE *f) {
- try {
- if (binario_floatIEEE4lsb && Melder_debug != 18) {
- float x32 = (float) x; // convert down, with loss of precision
- if (fwrite (& x32, sizeof (float), 1, f) != 1) writeError (U"a 32-bit floating-point number.");
- } else {
- uint8 bytes [4];
- int sign, exponent;
- double fMantissa, fsMantissa;
- uint32 mantissa;
- if (x < 0.0) { sign = 0x0100; x *= -1.0; }
- else sign = 0;
- if (x == 0.0) { exponent = 0; mantissa = 0; }
- else {
- fMantissa = frexp (x, & exponent);
- if ((exponent > 128) || ! (fMantissa < 1.0)) // Infinity or Not-a-Number
- { exponent = sign | 0x00FF; mantissa = 0; } // Infinity
- else { // finite
- exponent += 126; // add bias
- if (exponent <= 0) { // denormalized
- fMantissa = ldexp (fMantissa, exponent - 1);
- exponent = 0;
- }
- exponent |= sign;
- fMantissa = ldexp (fMantissa, 24);
- fsMantissa = floor (fMantissa);
- mantissa = (uint32) fsMantissa & 0x007F'FFFF;
- }
- }
- bytes [3] = (uint8) (exponent >> 1);
- bytes [2] = (uint8) ((exponent << 7) | (mantissa >> 16));
- bytes [1] = (uint8) (mantissa >> 8);
- bytes [0] = (uint8) mantissa;
- if (fwrite (bytes, sizeof (uint8), 4, f) != 4) writeError (U"four bytes.");
- }
- } catch (MelderError) {
- Melder_throw (U"Floating-point number not written to 4 bytes in binary file.");
- }
- }
- void binputr64 (double x, FILE *f) {
- try {
- if (binario_doubleIEEE8msb && Melder_debug != 18 || Melder_debug == 181) {
- if (fwrite (& x, sizeof (double), 1, f) != 1) writeError (U"a 64-bit floating-point number.");
- } else if (binario_doubleIEEE8lsb && Melder_debug != 18) {
- union { double xx; uint8 bytes [8]; };
- xx = x;
- uint8 tmp;
- tmp = bytes [0], bytes [0] = bytes [7], bytes [7] = tmp;
- tmp = bytes [1], bytes [1] = bytes [6], bytes [6] = tmp;
- tmp = bytes [2], bytes [2] = bytes [5], bytes [5] = tmp;
- tmp = bytes [3], bytes [3] = bytes [4], bytes [4] = tmp;
- if (fwrite (& xx, sizeof (double), 1, f) != 1) writeError (U"a 64-bit floating-point number.");
- } else {
- uint8 bytes [8];
- int sign, exponent;
- double fMantissa, fsMantissa;
- uint32 highMantissa, lowMantissa;
- if (x < 0.0) { sign = 0x0800; x *= -1.0; }
- else sign = 0;
- if (x == 0.0) { exponent = 0; highMantissa = 0; lowMantissa = 0; }
- else {
- fMantissa = frexp (x, & exponent);
- if (/*(exponent > 1024) ||*/ ! (fMantissa < 1.0)) // Infinity or Not-a-Number
- { exponent = sign | 0x07FF; highMantissa = 0; lowMantissa = 0; } // Infinity
- else { // finite
- exponent += 1022; // add bias
- if (exponent <= 0) { // denormalized
- fMantissa = ldexp (fMantissa, exponent - 1);
- exponent = 0;
- }
- exponent |= sign;
- fMantissa = ldexp (fMantissa, 21);
- fsMantissa = floor (fMantissa);
- highMantissa = (uint32) fsMantissa & 0x000F'FFFF;
- fMantissa = ldexp (fMantissa - fsMantissa, 32);
- fsMantissa = floor (fMantissa);
- lowMantissa = (uint32) fsMantissa;
- }
- }
- bytes [0] = (uint8) (exponent >> 4);
- bytes [1] = (uint8) ((exponent << 4) | (highMantissa >> 16));
- bytes [2] = (uint8) (highMantissa >> 8);
- bytes [3] = (uint8) highMantissa;
- bytes [4] = (uint8) (lowMantissa >> 24);
- bytes [5] = (uint8) (lowMantissa >> 16);
- bytes [6] = (uint8) (lowMantissa >> 8);
- bytes [7] = (uint8) lowMantissa;
- if (fwrite (bytes, sizeof (uint8), 8, f) != 8) writeError (U"eight bytes.");
- }
- } catch (MelderError) {
- Melder_throw (U"Floating-point number not written to 8 bytes in binary file.");
- }
- }
- void binputr80 (double x, FILE *f) {
- try {
- unsigned char bytes [10];
- Melder_assert (sizeof (int) > 2);
- int sign, exponent; // these should be uint16, but frexp() expects an int
- double fMantissa, fsMantissa;
- uint32 highMantissa, lowMantissa;
- if (x < 0.0) { sign = 0x8000; x *= -1.0; }
- else sign = 0;
- if (x == 0.0) { exponent = 0; highMantissa = 0; lowMantissa = 0; }
- else {
- fMantissa = frexp (x, & exponent);
- if ((exponent > 16384) || ! (fMantissa < 1.0)) // Infinity or Not-a-Number
- { exponent = sign | 0x7FFF; highMantissa = 0; lowMantissa = 0; } // Infinity
- else { // finite
- exponent += 16382; // add bias
- if (exponent < 0) { // denormalized
- fMantissa = ldexp (fMantissa, exponent);
- exponent = 0;
- }
- exponent |= sign;
- fMantissa = ldexp (fMantissa, 32);
- fsMantissa = floor (fMantissa);
- highMantissa = (uint32) fsMantissa;
- fMantissa = ldexp (fMantissa - fsMantissa, 32);
- fsMantissa = floor (fMantissa);
- lowMantissa = (uint32) fsMantissa;
- }
- }
- bytes [0] = (uint8) (exponent >> 8);
- bytes [1] = (uint8) exponent;
- bytes [2] = (uint8) (highMantissa >> 24);
- bytes [3] = (uint8) (highMantissa >> 16);
- bytes [4] = (uint8) (highMantissa >> 8);
- bytes [5] = (uint8) highMantissa;
- bytes [6] = (uint8) (lowMantissa >> 24);
- bytes [7] = (uint8) (lowMantissa >> 16);
- bytes [8] = (uint8) (lowMantissa >> 8);
- bytes [9] = (uint8) lowMantissa;
- if (fwrite (bytes, sizeof (uint8), 10, f) != 10) writeError (U"ten bytes.");
- } catch (MelderError) {
- Melder_throw (U"Floating-point number not written to 10 bytes in binary file.");
- }
- }
- dcomplex bingetc64 (FILE *f) {
- try {
- dcomplex result;
- result.re = bingetr32 (f);
- result.im = bingetr32 (f);
- return result;
- } catch (MelderError) {
- Melder_throw (U"Complex number not read from 8 bytes in binary file.");
- dcomplex result { };
- return result;
- }
- }
- dcomplex bingetc128 (FILE *f) {
- try {
- dcomplex result;
- result.re = bingetr64 (f);
- result.im = bingetr64 (f);
- return result;
- } catch (MelderError) {
- Melder_throw (U"Complex number not read from 16 bytes in binary file.");
- dcomplex result { };
- return result;
- }
- }
- void binputc64 (dcomplex z, FILE *f) {
- try {
- binputr32 (z.re, f);
- binputr32 (z.im, f);
- } catch (MelderError) {
- Melder_throw (U"Complex number not written to 8 bytes in binary file.");
- }
- }
- void binputc128 (dcomplex z, FILE *f) {
- try {
- binputr64 (z.re, f);
- binputr64 (z.im, f);
- } catch (MelderError) {
- Melder_throw (U"Complex number not written to 16 bytes in binary file.");
- }
- }
- autostring8 bingets8 (FILE *f) {
- try {
- unsigned int length = bingetu8 (f);
- autostring8 result (length);
- if (fread (result.get(), sizeof (char), length, f) != length)
- Melder_throw (feof (f) ? U"Reached end of file" : U"Error in file", U" while trying to read ", length, U" one-byte characters.");
- result [length] = 0; // trailing null byte
- return result;
- } catch (MelderError) {
- Melder_throw (U"Text not read from a binary file.");
- }
- }
- autostring8 bingets16 (FILE *f) {
- try {
- uint16 length = bingetu16 (f);
- autostring8 result (length);
- if (fread (result.get(), sizeof (char), length, f) != length)
- Melder_throw (feof (f) ? U"Reached end of file" : U"Error in file", U" while trying to read ", length, U" one-byte characters.");
- result [length] = 0; // trailing null byte
- return result;
- } catch (MelderError) {
- Melder_throw (U"Text not read from a binary file.");
- }
- }
- autostring8 bingets32 (FILE *f) {
- try {
- uint32 length = bingetu32 (f);
- autostring8 result (length);
- if (fread (result.get(), sizeof (char), length, f) != length)
- Melder_throw (feof (f) ? U"Reached end of file" : U"Error in file", U" while trying to read ", length, U" one-byte characters.");
- result [length] = 0; // trailing null byte
- return result;
- } catch (MelderError) {
- Melder_throw (U"Text not read from a binary file.");
- }
- }
- autostring32 bingetw8 (FILE *f) {
- try {
- autostring32 result;
- unsigned int length = bingetu8 (f);
- if (length == 0xFF) { // an escape for encoding
- /*
- UTF-16
- */
- length = bingetu8 (f);
- result = autostring32 (length);
- for (unsigned int i = 0; i < length; i ++) {
- char32 kar = bingetu16 (f);
- if ((kar & 0x00'F800) == 0x00'D800) {
- if (kar > 0x00'DBFF)
- Melder_throw (U"Incorrect Unicode value (first surrogate member ", kar, U").");
- char32 kar2 = bingetu16 (f);
- if (kar2 < 0x00'DC'00 || kar2 > 0x00'DF'FF)
- Melder_throw (U"Incorrect Unicode value (second surrogate member ", kar2, U").");
- result [i] = (((kar & 0x00'03FF) << 10) | (kar2 & 0x00'03FF)) + 0x01'0000;
- } else {
- result [i] = kar;
- }
- }
- } else {
- /*
- ASCII
- */
- result = autostring32 (length);
- for (unsigned int i = 0; i < length; i ++) {
- result [i] = bingetu8 (f);
- }
- }
- result [length] = U'\0';
- return result;
- } catch (MelderError) {
- Melder_throw (U"Text not read from a binary file.");
- }
- }
- autostring32 bingetw16 (FILE *f) {
- try {
- autostring32 result;
- uint16 length = bingetu16 (f);
- if (length == 0xFFFF) { // an escape for encoding
- /*
- UTF-16
- */
- length = bingetu16 (f);
- result = autostring32 (length);
- for (uint16 i = 0; i < length; i ++) {
- char32 kar = (char32) (char16) bingetu16 (f);
- if ((kar & 0x00'F800) == 0x00'D800) {
- if (kar > 0x00'DBFF)
- Melder_throw (U"Incorrect Unicode value (first surrogate member ", kar, U").");
- char32 kar2 = (char32) (char16) bingetu16 (f);
- if (kar2 < 0x00'DC00 || kar2 > 0x00'DFFF)
- Melder_throw (U"Incorrect Unicode value (second surrogate member ", kar2, U").");
- result [i] = (((kar & 0x00'03FF) << 10) | (kar2 & 0x00'03FF)) + 0x01'0000;
- } else {
- result [i] = kar;
- }
- }
- } else {
- /*
- ASCII
- */
- result = autostring32 (length);
- for (unsigned short i = 0; i < length; i ++) {
- result [i] = (char32) (char8) bingetu8 (f);
- }
- }
- result [length] = U'\0';
- return result;
- } catch (MelderError) {
- Melder_throw (U"Text not read from a binary file.");
- }
- }
- autostring32 bingetw32 (FILE *f) {
- try {
- autostring32 result;
- uint32 length = bingetu32 (f);
- if (length == 0xFFFF'FFFF) { // an escape for encoding
- /*
- UTF-16
- */
- length = bingetu32 (f);
- result = autostring32 (length);
- for (uint32 i = 0; i < length; i ++) {
- char32 kar = bingetu16 (f);
- if ((kar & 0x00'F800) == 0x00'D800) {
- if (kar > 0x00'DBFF)
- Melder_throw (U"Incorrect Unicode value (first surrogate member ", kar, U").");
- char32 kar2 = bingetu16 (f);
- if (kar2 < 0x00'DC00 || kar2 > 0x00'DFFF)
- Melder_throw (U"Incorrect Unicode value (second surrogate member ", kar2, U").");
- result [i] = (((kar & 0x00'03FF) << 10) | (kar2 & 0x00'03FF)) + 0x01'0000;
- } else {
- result [i] = kar;
- }
- }
- } else {
- /*
- ASCII
- */
- result = autostring32 (length);
- for (uint32 i = 0; i < length; i ++) {
- result [i] = bingetu8 (f);
- }
- }
- result [length] = U'\0';
- return result;
- } catch (MelderError) {
- Melder_throw (U"Text not read from a binary file.");
- }
- }
- void binputs8 (const char *s, FILE *f) {
- try {
- if (! s) {
- binputu8 (0, f);
- } else {
- size_t length = strlen (s);
- if (length > UINT8_MAX) {
- Melder_warning (U"Text of ", length, U" characters truncated to 255 characters.");
- length = UINT8_MAX;
- }
- binputu8 (length, f);
- if (fwrite (s, sizeof (char), length, f) != length)
- Melder_throw (U"Error in file while trying to write ", length, U" one-byte characters.");
- }
- } catch (MelderError) {
- Melder_throw (U"Text not written to a binary file.");
- }
- }
- void binputs16 (const char *s, FILE *f) {
- try {
- if (! s) {
- binputu16 (0, f);
- } else {
- size_t length = strlen (s);
- if (length > UINT16_MAX) {
- Melder_warning (U"Text of ", length, U" characters truncated to 65535 characters.");
- length = UINT16_MAX;
- }
- binputu16 ((uint16) length, f); // safe conversion down
- if (fwrite (s, sizeof (char), length, f) != length)
- Melder_throw (U"Error in file while trying to write ", length, U" one-byte characters.");
- }
- } catch (MelderError) {
- Melder_throw (U"Text not written to a binary file.");
- }
- }
- void binputs32 (const char *s, FILE *f) {
- try {
- if (! s) {
- binputu32 (0, f);
- } else {
- size_t length = strlen (s);
- if (length > UINT32_MAX) {
- Melder_warning (U"Text of ", length, U" characters truncated to 4,294,967,295 characters.");
- length = UINT32_MAX;
- }
- binputu32 (length, f);
- if (fwrite (s, sizeof (char), length, f) != length)
- Melder_throw (U"Error in file while trying to write ", length, U" one-byte characters.");
- }
- } catch (MelderError) {
- Melder_throw (U"Text not written to a binary file.");
- }
- }
- static inline void binpututf16 (char32 kar, FILE *f) {
- if (kar <= 0x00FFFF) {
- binputu16 ((uint16) kar, f); // truncate to lower 16 bits
- } else if (kar <= 0x10'FFFF) {
- kar -= 0x01'0000;
- binputu16 ((uint16) (0x00'D800 | (kar >> 10)), f);
- binputu16 ((uint16) (0x00'DC00 | (kar & 0x00'03FF)), f);
- } else {
- Melder_fatal (U"Impossible Unicode value.");
- }
- }
- void binputw8 (conststring32 s, FILE *f) {
- try {
- if (! s) {
- binputu8 (0, f);
- } else {
- uint32 length = str32len (s);
- if (length > UINT8_MAX - 1) {
- Melder_warning (U"Text of ", length, U" characters truncated to 254 characters.");
- length = UINT8_MAX - 1;
- }
- if (Melder_isValidAscii (s)) {
- /*
- * ASCII
- */
- binputu8 (length, f);
- for (size_t i = 0; i < length; i ++) {
- binputu8 ((unsigned int) (char) s [i], f);
- }
- } else {
- /*
- * UTF-16
- */
- binputu8 (0xFF, f); // an escape for multibyte encoding
- binputu8 (length, f);
- for (size_t i = 0; i < length; i ++) {
- binpututf16 (s [i], f);
- }
- }
- }
- } catch (MelderError) {
- Melder_throw (U"Text not written to a binary file.");
- }
- }
- void binputw16 (conststring32 s, FILE *f) {
- try {
- if (! s) {
- binputu16 (0, f);
- } else {
- int64 length = str32len (s);
- if (length > UINT16_MAX - 1) {
- Melder_warning (U"Text of ", length, U" characters truncated to 65534 characters.");
- length = UINT16_MAX - 1;
- }
- if (Melder_isValidAscii (s)) {
- /*
- * ASCII
- */
- binputu16 ((uint16) length, f);
- for (int64 i = 0; i < length; i ++) {
- binputu8 ((unsigned int) (char8) s [i], f);
- }
- } else {
- /*
- * UTF-16
- */
- binputu16 (0xFFFF, f); // an escape for multibyte encoding
- binputu16 ((uint16) length, f);
- for (int64 i = 0; i < length; i ++) {
- binpututf16 (s [i], f);
- }
- }
- }
- } catch (MelderError) {
- Melder_throw (U"Text not written to a binary file.");
- }
- }
- void binputw32 (conststring32 s, FILE *f) {
- try {
- if (! s) {
- binputu32 (0, f);
- } else {
- int64 length = str32len (s);
- if (length > UINT32_MAX - 1) {
- Melder_warning (U"Text of ", length, U" characters truncated to 4,294,967,294 characters.");
- length = UINT32_MAX - 1;
- }
- if (Melder_isValidAscii (s)) {
- /*
- * ASCII
- */
- binputu32 ((uint32) length, f);
- for (int64 i = 0; i < length; i ++) {
- binputu8 ((unsigned int) (char) s [i], f);
- }
- } else {
- /*
- * UTF-16
- */
- binputu32 (0xFFFF'FFFF, f); // an escape for multibyte encoding
- binputu32 ((uint32) length, f);
- for (int64 i = 0; i < length; i ++) {
- binpututf16 (s [i], f);
- }
- }
- }
- } catch (MelderError) {
- Melder_throw (U"Text not written to a binary file.");
- }
- }
- /* End of file abcio.cpp */
|