environmentCodec.cpp

00001 /*
00002   環境情報のコーデック
00003   Satofumi KAMIMURA
00004   $Id$
00005 */
00006 
00007 #include "environmentCodec.h"
00008 #include <ctype.h>
00009 
00010 
00011 enum {
00012   env_Fail = EnvironmentCodecStream::Fail,
00013 };
00014 
00015 
00016 static bool isLF(char ch) {
00017   return ((ch == '\r') || (ch == '\n')) ? true : false;
00018 }
00019 
00020 
00021 void EnvironmentCodecStream::read1ch(void) {
00022   char ch = get1ch();
00023 
00024   // !!! 本来は、文字、文字列内の # をちゃんと扱うべき
00025   while (ch == '#') {
00026     while (!eof()) {
00027       ch = get1ch();
00028       if (isLF(ch)) {
00029         ch = get1ch();
00030         break;
00031       }
00032     }
00033   }
00034   buffer.push_back(ch);
00035 }
00036 
00037 
00038 void EnvironmentCodecStream::clearBuffer(int n) {
00039   if (n <= All) {
00040     buffer.clear();
00041 
00042   } else {
00043     int remove_size = (static_cast<unsigned int>(n) > buffer.size()) ?
00044       static_cast<int>(buffer.size()) : n;
00045     buffer.erase(buffer.begin(), buffer.begin() + remove_size);
00046   }
00047 }
00048 
00049 
00050 static void readRequireSize(EnvironmentCodecStream& codec, int offset,
00051                             int require_size) {
00052 
00053   int read_size =
00054     static_cast<int>((require_size + offset) - codec.buffer.size());
00055   for (int i = 0; i < read_size; ++i) {
00056     codec.read1ch();
00057   }
00058 }
00059 
00060 
00061 static int compareToText(const char* text,
00062                          EnvironmentCodecStream& codec, int offset) {
00063   unsigned int require_size = static_cast<unsigned int>(strlen(text));
00064   readRequireSize(codec, offset, require_size);
00065   if ((codec.buffer.size() < require_size) ||
00066       strncmp(text, &codec.buffer[offset], require_size)) {
00067     return env_Fail;
00068   }
00069   return require_size;
00070 }
00071 
00072 
00073 // 改行               := '\r' | '\n'
00074 extern int encodeLineFeedFromText(EnvironmentCodecStream& codec, int offset) {
00075   readRequireSize(codec, offset, 1);
00076   if ((codec.buffer.size() - offset) < 1) {
00077     return env_Fail;
00078   }
00079   return (isLF(codec.buffer[offset])) ? 1 : 0;
00080 }
00081 
00082 
00083 // 空白               := ( ' ' | '\t' | (改行)) [空白]
00084 extern int encodeSpaceFromText(EnvironmentCodecStream& codec, int offset,
00085                                int require_size) {
00086   unsigned int index = offset;
00087   readRequireSize(codec, index, require_size);
00088 
00089   for (readRequireSize(codec,index,1);
00090        (codec.buffer.size() > index) && (isspace(codec.buffer[index]));
00091        ++index) {
00092     readRequireSize(codec, index, 1);
00093   }
00094   return index - offset;
00095 }
00096 
00097 
00098 // 数字               := 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
00099 // 数字列    := (数字) [数字列]
00100 // 数値               := [ + | - ] (数字列)
00101 extern int encodeNumericFromText(EnvironmentCodecStream& codec, int offset,
00102                                  int* numeric) {
00103   int index = offset;
00104   int sign = +1;
00105   int num = 0;
00106 
00107   // 符号
00108   readRequireSize(codec, offset, 1);
00109   if ((codec.buffer[index] == '-') || (codec.buffer[index] == '+')) {
00110     if (codec.buffer[index] == '-') {
00111       sign = -1;
00112     }
00113     ++index;
00114     readRequireSize(codec, index, 1);
00115   }
00116 
00117   // 数値
00118   while (1) {
00119     readRequireSize(codec, index, 1);
00120     if (isdigit(codec.buffer[index])) {
00121       num = (num * 10) + (codec.buffer[index] - '0');
00122       ++index;
00123     } else {
00124       break;
00125     }
00126   }
00127   *numeric = sign * num;
00128   return index - offset;
00129 }
00130 
00131 
00132 //  点         := '(' [空白] (数値) [空白] ',' [空白] (数値) [空白] ')'
00133 int encodeAPointFromText(EnvironmentCodecStream& codec, int offset,
00134                          VXV::Grid3D& point) {
00135   int index = offset;
00136 
00137   // '('
00138   int n = compareToText("(", codec, index);
00139   if (n <= 0) {
00140     return env_Fail;
00141   }
00142   index += n;
00143 
00144   // [空白]
00145   index += encodeSpaceFromText(codec, index);
00146 
00147   // (数値)
00148   int x = 0;
00149   n = encodeNumericFromText(codec, index, &x);
00150   if (n <= 0) {
00151     return env_Fail;
00152   }
00153   index += n;
00154 
00155   // [空白]
00156   index += encodeSpaceFromText(codec, index);
00157 
00158   // ','
00159   n = compareToText(",", codec, index);
00160   if (n <= 0) {
00161     return env_Fail;
00162   }
00163   index += n;
00164 
00165   // [空白]
00166   index += encodeSpaceFromText(codec, index);
00167 
00168   // (数値)
00169   int y = 0;
00170   n = encodeNumericFromText(codec, index, &y);
00171   if (n <= 0) {
00172     return env_Fail;
00173   }
00174   index += n;
00175 
00176   // [空白]
00177   index += encodeSpaceFromText(codec, index);
00178 
00179   // ')'
00180   n = compareToText(")", codec, index);
00181   if (n <= 0) {
00182     return env_Fail;
00183   }
00184   point = VXV::Grid3D(x, y, 0);
00185   index += n;
00186 
00187   return index - offset;
00188 }
00189 
00190 
00191 // 点列               := (点) [空白] [点列]
00192 int encodePointsFromText(EnvironmentCodecStream& codec, int offset,
00193                          std::vector<VXV::Grid3D>& points) {
00194   int index = offset;
00195 
00196   // (点)
00197   VXV::Grid3D tmp_point;
00198   int n = encodeAPointFromText(codec, index, tmp_point);
00199   if (n <= 0) {
00200     return env_Fail;
00201   }
00202   index += n;
00203   points.push_back(tmp_point);
00204 
00205   do {
00206     // [空白]
00207     index += encodeSpaceFromText(codec, index);
00208 
00209     // [点列]
00210     n = encodeAPointFromText(codec, index, tmp_point);
00211     if (n > 0) {
00212       index += n;
00213       points.push_back(tmp_point);
00214     }
00215   } while (n > 0);
00216   return index - offset;
00217 }
00218 
00219 
00220 // ポリゴン := '(polygon' (空白) (点列) [空白] ')'
00221 int encodePolygonFromText(EnvironmentCodecStream& codec, int offset,
00222                           std::vector<CoordinateCtrl::polygon_t>& polygons) {
00223   int index = offset;
00224 
00225   // '(polygon'
00226   int n = compareToText("(polygon", codec, index);
00227   if (n <= 0) {
00228     return env_Fail;
00229   }
00230   index += n;
00231 
00232   // (空白)
00233   n = encodeSpaceFromText(codec, index, 1);
00234   if (n <= 0) {
00235     return env_Fail;
00236   }
00237   index += n;
00238 
00239   // (点列)
00240   std::vector<VXV::Grid3D> tmp_points;
00241   n = encodePointsFromText(codec, index, tmp_points);
00242   if (n <= 0) {
00243     return env_Fail;
00244   }
00245   index += n;
00246 
00247   // [空白]
00248   index += encodeSpaceFromText(codec, index);
00249 
00250   // ')'
00251   n = compareToText(")", codec, index);
00252   if (n <= 0) {
00253     return env_Fail;
00254   }
00255   polygons.push_back(tmp_points);
00256 
00257   index += n;
00258   return index - offset;
00259 }
00260 

Generated on Mon Apr 13 22:52:03 2009 by  doxygen 1.5.7.1